MonoTouch.Dialog 崩溃 [英] MonoTouch.Dialog crash

查看:25
本文介绍了MonoTouch.Dialog 崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小的测试应用程序,它只是在 3 页之间循环.这是 AppDelegate:

I have a small test app which just cycles between 3 pages. Here is AppDelegate:

    public override bool FinishedLaunching (UIApplication app, NSDictionary options)
    {
        _session = new Session();
        _session.NextScreen += (screenIndex) => 
        {
            window.RootViewController = _viewControllers[screenIndex];
        };

        _viewControllers.Add(new Screen0(_session));
        _viewControllers.Add(new Screen1(_session));
        _viewControllers.Add(new Screen2(_session));

        // create a new window instance based on the screen size
        window = new UIWindow (UIScreen.MainScreen.Bounds);

        // If you have defined a view, add it here:
        // window.AddSubview (navigationController.View);
        window.RootViewController = _viewControllers[0];

        // make the window visible
        window.MakeKeyAndVisible ();

        return true;

如果我在每个屏幕上放一个按钮,我就可以在页面之间导航,即

If I put a button on each screen I can navigate from page to page, i.e.,

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();

        UIButton button = new UIButton(new RectangleF(30, 200, 80, 34));
        button.SetTitle("Go to 1", UIControlState.Normal);
        button.TouchUpInside += (sender, e) => 
        {
            _session.ExittingScreen = 0;
        };
        View.AddSubview(button);
    }

然而,当我使用 MonoTouch.Dialog 时,我会间歇性崩溃.这是我的代码:

WHen I use MonoTouch.Dialog however, I get intermitten crashes. Here's my code:

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();

        var rootElement = new RootElement("Register")
        {
            new Section()
            {
                new EntryElement("First Name", "required", ""),
                new EntryElement("Last Name", "required", ""),
                new EntryElement("Email Address", "required", ""),
                new EntryElement("Password", "required", "")
            },
            new Section()
            {
                new StyledStringElement("Submit you information", () => { _session.ExittingScreen = 1; })
            }
        };
        var dialogViewController = new DialogViewController(rootElement);
        var navigationController = new UINavigationController(dialogViewController);

        View.Add (navigationController.View);

和转储:

at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication.UIApplicationMain (int,string[],intptr,intptr) <0xffffffff>在 MonoTouch.UIKit.UIApplication.Main (string[],string,string) <0x000b7>在 MTD.Application.Main (string[]) <0x00017>at (wrapper runtime-invoke) .runtime_invoke_void_object (object,intptr,intptr,intptr) <0xffffffff>

at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication.UIApplicationMain (int,string[],intptr,intptr) <0xffffffff> at MonoTouch.UIKit.UIApplication.Main (string[],string,string) <0x000b7> at MTD.Application.Main (string[]) <0x00017> at (wrapper runtime-invoke) .runtime_invoke_void_object (object,intptr,intptr,intptr) <0xffffffff>

本机堆栈跟踪:

0   MTD                                 0x00090b7c mono_handle_native_sigsegv + 284
1   MTD                                 0x00005f28 mono_sigsegv_signal_handler + 248
2   libsystem_c.dylib                   0x97da559b _sigtramp + 43
3   ???                                 0xffffffff 0x0 + 4294967295
4   UIKit                               0x02220952 -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 201
5   Foundation                          0x0173786d __NSFireDelayedPerform + 389
6   CoreFoundation                      0x01195966 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
7   CoreFoundation                      0x01195407 __CFRunLoopDoTimer + 551
8   CoreFoundation                      0x010f87c0 __CFRunLoopRun + 1888
9   CoreFoundation                      0x010f7db4 CFRunLoopRunSpecific + 212
10  CoreFoundation                      0x010f7ccb CFRunLoopRunInMode + 123
11  GraphicsServices                    0x04789879 GSEventRunModal + 207
12  GraphicsServices                    0x0478993e GSEventRun + 114
13  UIKit                               0x02190a9b UIApplicationMain + 1175
14  ???                                 0x09ff6774 0x0 + 167733108
15  ???                                 0x09ff5958 0x0 + 167729496
16  ???                                 0x09ff57f0 0x0 + 167729136
17  ???                                 0x09ff587f 0x0 + 167729279
18  MTD                                 0x0000a292 mono_jit_runtime_invoke + 722
19  MTD                                 0x0016a17e mono_runtime_invoke + 126
20  MTD                                 0x0016e264 mono_runtime_exec_main + 420
21  MTD                                 0x00173685 mono_runtime_run_main + 725
22  MTD                                 0x00067495 mono_jit_exec + 149
23  MTD                                 0x002116c9 main + 2825
24  MTD                                 0x000032e5 start + 53

25 ???0x00000005 0x0 + 5

25 ??? 0x00000005 0x0 + 5  

我做错了什么,还是这是一个错误?谢谢.

Am I doing something wrong, or is this a bug? Thanks.

推荐答案

避免以下模式:

var navigationController = new UINavigationController(dialogViewController);
View.Add (navigationController.View);

因为一旦 View.Add 调用完成并且垃圾收集器可以处置它(无论何时).然而,从本地方面来看,它预计会存在.返回(从本机托管)到已处置实例的调用将使您的应用程序崩溃.

because navigationController won't be referenced (on the managed side) once the View.Add call is done and the garbage collector can dispose it (whenever it wants). However from the native side it will be expected to exist. Calls going back (from native to managed) to the disposed instance will crash your application.

正确的模式是将 navigationController 声明为您类型的字段(而不是局部变量)并在方法中创建/分配它.只要父实例存在,这将保持对 navigationController 的引用(并确保任何回调不会转到已处置的对象).

The right pattern is to declare navigationController as a field (instead of a local variable) of your type and create/assign it in the method. This will keep a reference to navigationController alive as long as the parent instance exists (and ensure any callback won't go to a disposed object).

例如

private UINavigationController navigationController;
...
public override void ViewDidLoad ()
{
    ...
    var dialogViewController = new DialogViewController(rootElement);
    navigationController = new UINavigationController(dialogViewController);

    View.Add (navigationController.View);
    ...
}

这篇关于MonoTouch.Dialog 崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆