首先,我使用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