为什么MonoTouch运行时与UIAlertView崩溃?

时间:2012-01-13 19:03:01

标签: c# ios5 xamarin.ios

我有一个扩展UIAlertView的旧C#类,用于提示用户输入IP地址。它还将保留IP地址并将其作为默认条目值加载。

原始代码攻击iOS4.x UIAlertView以添加文本字段,并且它有几个布局问题。我将代码转换为使用iOS5 UIAlertView的{​​{1}}设置,一切正常。

我被要求在弹出键盘上启用完成键,以便它可以是连接按钮的快捷方式。我在代码的构造函数中添加了如下代码:

AlertViewStyle

该类被如此使用:

public AddressAlertView()
{
    AddButton("Cancel");
    AddButton("Connect");
    AlertViewStyle = UIAlertViewStyle.PlainTextInput;

    // NEW - get input text field, enable Done on the keyboard and
    // allow Done to be the same as the Connect button
    UITextField fld = GetTextField(0);
    fld.ReturnKeyType = UIReturnKeyType.Done;
    fld.ShouldReturn = (textField) =>
    {
        DismissWithClickedButtonIndex(1, true);
        return textField.ResignFirstResponder();
    };
    // *** end of new code ***

    // restore saved IP address
    string savedAddress = NSUserDefault.StandardUserDefaults.StringForKey(AddressKey);
    if (savedAddress != null)
        fld.Text = savedAddress;
}

现在问题。运行此代码时,.... AddressAlertView addrPrompt = new AddressAlertView(); addrPrompt.Title = "IP Address"; addrPrompt.Message = "Enter address"; addrPrompt.Dismissed += (sender, e) => { if (e.ButtonIndex == 1) { // use IP address... .... } }; addrPrompt.Show(); .... 会正确显示弹出对话框,一切都像以前一样工作。但是,如果我点按键盘上的完成,该应用就会在AddressAlertView内轰炸。

我尝试将新代码移到UIAlertView方法,但它仍然崩溃。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

您需要将AddressAlertView声明为类成员:

AddressAlertView addrPrompt;
public void DoSomething()
{

    addrPrompt = new AddressAlertView();
    //etc

}

这种情况下的问题(我和UIAlertViews有很多相似之处)是AddressAlertView对象是GC'd而事件处理程序导致崩溃。要确保这是问题,请不要更改任何内容,只需删除/评论addrPrompt.Dismissed += ...行并再次测试即可。如果它没有崩溃,那么这就是解决方案。

答案 1 :(得分:0)

答案 2 :(得分:0)

想出来。在查看MonoTouch的跟踪转储输出时,提到了一个无效对象。我没有将文本字段作为局部变量,而是将对它的引用保存为实例变量:

private UITextField _addressTextField = null;

我将构造函数中的代码更改为:

_addressTextField = GetTextField(0);

瞧!这解决了崩溃。毫无疑问,本地UITextField变量正在获取GC,导致ShouldReturn lambda表达式被调用时崩溃。