首先,我使用Xamarin Studio 6.1.3以防有所作为。获取NullReferenceException,除非我在调试时展开基类对象
我正在创建一个简单的应用程序,并希望登录表单显示为工作表。我遵循Xamarin教程创建工作表(https://developer.xamarin.com/guides/mac/user-interface/working-with-dialogs/#Creating_a_Custom_Sheet),但遇到了问题。
每本教程中,我创建了一个类:
using System;
using Foundation;
using AppKit;
namespace SampleProject
{
public partial class UserLoginController : NSViewController
{
private NSViewController _presentor;
public string Username
{
get { return TxtUsername.StringValue; }
set { TxtUsername.StringValue = value; }
}
public string Password
{
get { return TxtPassword.StringValue; }
set { TxtPassword.StringValue = value; }
}
public NSViewController Presentor
{
get { return _presentor; }
set { _presentor = value; }
}
public UserLoginController(IntPtr handle) : base(handle)
{
}
private void CloseDialog()
{
Presentor.DismissViewController(this);
}
partial void BtnCancelClick(NSObject sender)
{
RaiseDialogCanceled();
CloseDialog();
}
partial void BtnLoginClick(NSObject sender)
{
RaiseDialogAccepted();
CloseDialog();
}
public EventHandler DialogAccepted;
internal void RaiseDialogAccepted()
{
if (this.DialogAccepted != null)
this.DialogAccepted(this, EventArgs.Empty);
}
public EventHandler DialogCanceled;
internal void RaiseDialogCanceled()
{
if (this.DialogCanceled != null)
this.DialogCanceled(this, EventArgs.Empty);
}
}
}
而且我在我的ViewController类增加了PrepareForSegue一个覆盖:
public override void PrepareForSegue(NSStoryboardSegue segue, NSObject sender)
{
base.PrepareForSegue(segue, sender);
switch (segue.Identifier)
{
case "UserLoginSegue":
UserLoginController loginSheet = segue.DestinationController as UserLoginController;
loginSheet.Username = ""; //This line throws NullReferenceException unless I set a breakpoint and expand loginSheet.Base before allowing this line to execute.
loginSheet.Password = "";
loginSheet.Presentor = this;
loginSheet.DialogAccepted += (object s, EventArgs e) => { Console.WriteLine("OK Clicked"); };
loginSheet.DialogCanceled += (object s, EventArgs e) => { Console.WriteLine("Cancel Clicked"); };
break;
}
}
看到上面的代码块的注释。我基本上在该行上设置了一个断点,当它触发时,我检查了loginSheet对象。如果我展开Base对象来检查它,然后继续执行,则所有事情都按预期工作。如果我不这样做,只要代码尝试访问UserLoginController类中的任何字段/属性/方法,就会得到一个NullReferenceException。
我完全不知道为什么会发生这种情况。我在UserLoginController的构造函数中设置了一个断点,并验证了它是用句柄调用的,并且基类构造函数也应该被调用。
我已经通读了几遍教程,没有看到任何我错过的东西。似乎无法找到其他人有相同的问题。
我的最终问题是:我能做些什么来使代码按预期工作?
为了学习(这可能揭示问题):在调试时检查UserLoginController类的基础对象时发生了什么?
“如果此属性的值在访问它时尚未设置,则视图控制器会调用loadView方法。该方法依次设置视图控制器的nibName和nibBundle属性标识的nib文件的视图。“ - https://developer.apple.com/reference/appkit/nsviewcontroller/1434401-view?language=objc –
With这个新发现的信息我将调用LoadView(),而不是检查View属性,但根据LoadView的Apple文档(https://developer.apple.com/reference/appkit/nsviewcontroller/1434405-loadview?language=objc) - “不要调用这个方法。如果您需要调用此方法,请访问视图属性。“该链接提供了更多有关直接调用LoadView方法的原因的更多信息。 – John