MonoTouch.Dialog 崩溃 [英] MonoTouch.Dialog crash
问题描述
我有一个小的测试应用程序,它只是在 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屋!