为什么我在 Xamarin.Forms 中订阅事件时收到 NullReferenceException,但仅在 iOS 中?
Why am I getting a NullReferenceException when subscribing to event in Xamarin.Forms, but only on iOS?
我有一个页面 - 页面 A,它有一个订阅另一个页面 - 页面 B 上的事件的方法。我想我可以在页面 A 中的代码中实例化页面 B,然后再在页面 A 中订阅我的方法到页面B中的事件,然后最终将页面B推送到导航堆栈。
不幸的是,当我在 iOS 上测试我的应用程序时,我不断在该方法订阅事件的行上收到 NullReferenceException。当我作为 Android 应用程序部署和测试时,代码运行得非常好,但我总是在 iOS 上得到 NullReferenceException。是什么导致抛出此异常,我该如何解决?为什么它是特定于 iOS 的平台?
页面 A 上的代码
var confirmationPage = new EmailConfirmationPage(username);
confirmationPage.EmailConfirmed += this.OnEmailConfirmed;
await this.Navigation.PushModalAsync(confirmationPage);
...
private void OnEmailConfirmed(object source, EventArgs args)
{
this.LabelMessage.Text = "Email Confirmed!";
}
页面 B 上的代码
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace appFBLA2019
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class EmailConfirmationPage : ContentPage
{
private string username;
private string email;
public delegate void EmailConfirmedEventHandler(object source, EventArgs args);
public event EmailConfirmedEventHandler EmailConfirmed;
public EmailConfirmationPage(string username)
{
InitializeComponent();
this.username = username;
this.LabelTitle.Text = "Loading...";
GetEmail();
}
private void GetEmail()
{
try
{
ServerConnector.QueryDB($"getEmail/{this.username}/-");
this.email = ServerConnector.ReceiveFromDB();
this.LabelTitle.Text = $"Enter the confirmation code sent to {this.email.Split('/')[1]}";
}
catch
{
this.LabelMessage.Text = "Connection Error: Please Try Again.";
}
}
private async void ButtonConfirmEmail_Clicked(object sender, EventArgs e)
{
try
{
string userInputToken = this.EntryConfirmationCode.Text.Trim();
ServerConnector.QueryDB($"confirmEmail/{this.username}/{userInputToken}/-");
string returnData = ServerConnector.ReceiveFromDB();
if (returnData == "true/-")
{
OnEmailConfirmed();
await this.Navigation.PopModalAsync(true);
}
else
{
this.LabelMessage.Text = "Email could not be confirmed. Please try your code again.";
}
}
catch
{
this.LabelMessage.Text = "Connection Error: Please try again.";
}
}
private void ButtonFixEmail_Clicked(object sender, EventArgs e)
{
string newEmail = this.EntryChangeEmail.Text;
ServerConnector.QueryDB($"changeEmail/{this.username}/{newEmail}/-");
string result = ServerConnector.ReceiveFromDB();
if (result == "true/-")
{
this.LabelMessage.Text = $"Enter the confirmation code sent to {newEmail}";
}
else
{
this.LabelMessage.Text = $"Email could not be changed: {result.Split('/')[1]}";
}
}
private async void ButtonClose_Clicked(object sender, EventArgs e)
{
await this.Navigation.PopModalAsync(true);
}
protected virtual void OnEmailConfirmed()
{
EmailConfirmed?.Invoke(this, EventArgs.Empty);
}
}
}
在订阅事件方法之前调用堆栈:
0xC0 in appFBLA2019.CreateAccountPage.ButtonCreateAccount_Clicked at C:\Users\chung\source\repos\appFBLA2019\appFBLA2019\appFBLA2019\CreateAccountPage.xaml.cs:30,21 C#
将方法订阅到事件后调用堆栈:
0x1B8 in appFBLA2019.CreateAccountPage.ButtonCreateAccount_Clicked at C:\Users\chung\source\repos\appFBLA2019\appFBLA2019\appFBLA2019\CreateAccountPage.xaml.cs:39,13 C#
经过进一步测试,我注意到 iOS 和 Android 都会出现此问题,但仅当 运行 使用 Xamarin Live Player 的应用程序时才会出现此问题。我联系了 Microsoft,不幸的是,他们指出 Xamarin Live Player 存在局限性。直接部署到设备上没有问题,代码运行正常。
我有一个页面 - 页面 A,它有一个订阅另一个页面 - 页面 B 上的事件的方法。我想我可以在页面 A 中的代码中实例化页面 B,然后再在页面 A 中订阅我的方法到页面B中的事件,然后最终将页面B推送到导航堆栈。
不幸的是,当我在 iOS 上测试我的应用程序时,我不断在该方法订阅事件的行上收到 NullReferenceException。当我作为 Android 应用程序部署和测试时,代码运行得非常好,但我总是在 iOS 上得到 NullReferenceException。是什么导致抛出此异常,我该如何解决?为什么它是特定于 iOS 的平台?
页面 A 上的代码
var confirmationPage = new EmailConfirmationPage(username);
confirmationPage.EmailConfirmed += this.OnEmailConfirmed;
await this.Navigation.PushModalAsync(confirmationPage);
...
private void OnEmailConfirmed(object source, EventArgs args)
{
this.LabelMessage.Text = "Email Confirmed!";
}
页面 B 上的代码
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace appFBLA2019
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class EmailConfirmationPage : ContentPage
{
private string username;
private string email;
public delegate void EmailConfirmedEventHandler(object source, EventArgs args);
public event EmailConfirmedEventHandler EmailConfirmed;
public EmailConfirmationPage(string username)
{
InitializeComponent();
this.username = username;
this.LabelTitle.Text = "Loading...";
GetEmail();
}
private void GetEmail()
{
try
{
ServerConnector.QueryDB($"getEmail/{this.username}/-");
this.email = ServerConnector.ReceiveFromDB();
this.LabelTitle.Text = $"Enter the confirmation code sent to {this.email.Split('/')[1]}";
}
catch
{
this.LabelMessage.Text = "Connection Error: Please Try Again.";
}
}
private async void ButtonConfirmEmail_Clicked(object sender, EventArgs e)
{
try
{
string userInputToken = this.EntryConfirmationCode.Text.Trim();
ServerConnector.QueryDB($"confirmEmail/{this.username}/{userInputToken}/-");
string returnData = ServerConnector.ReceiveFromDB();
if (returnData == "true/-")
{
OnEmailConfirmed();
await this.Navigation.PopModalAsync(true);
}
else
{
this.LabelMessage.Text = "Email could not be confirmed. Please try your code again.";
}
}
catch
{
this.LabelMessage.Text = "Connection Error: Please try again.";
}
}
private void ButtonFixEmail_Clicked(object sender, EventArgs e)
{
string newEmail = this.EntryChangeEmail.Text;
ServerConnector.QueryDB($"changeEmail/{this.username}/{newEmail}/-");
string result = ServerConnector.ReceiveFromDB();
if (result == "true/-")
{
this.LabelMessage.Text = $"Enter the confirmation code sent to {newEmail}";
}
else
{
this.LabelMessage.Text = $"Email could not be changed: {result.Split('/')[1]}";
}
}
private async void ButtonClose_Clicked(object sender, EventArgs e)
{
await this.Navigation.PopModalAsync(true);
}
protected virtual void OnEmailConfirmed()
{
EmailConfirmed?.Invoke(this, EventArgs.Empty);
}
}
}
在订阅事件方法之前调用堆栈:
0xC0 in appFBLA2019.CreateAccountPage.ButtonCreateAccount_Clicked at C:\Users\chung\source\repos\appFBLA2019\appFBLA2019\appFBLA2019\CreateAccountPage.xaml.cs:30,21 C#
将方法订阅到事件后调用堆栈:
0x1B8 in appFBLA2019.CreateAccountPage.ButtonCreateAccount_Clicked at C:\Users\chung\source\repos\appFBLA2019\appFBLA2019\appFBLA2019\CreateAccountPage.xaml.cs:39,13 C#
经过进一步测试,我注意到 iOS 和 Android 都会出现此问题,但仅当 运行 使用 Xamarin Live Player 的应用程序时才会出现此问题。我联系了 Microsoft,不幸的是,他们指出 Xamarin Live Player 存在局限性。直接部署到设备上没有问题,代码运行正常。