Crash MonoTouch.Dialog

J’ai une petite application de test qui passe de 3 pages à la fois. Voici 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; 

Si je mets un bouton sur chaque écran, je peux naviguer de page en page, c.-à-d.

  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); } 

Cependant, lorsque j’utilise MonoTouch.Dialog, j’ai des chutes intermittentes. Voici mon 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 StyledSsortingngElement("Submit you information", () => { _session.ExittingScreen = 1; }) } }; var dialogViewController = new DialogViewController(rootElement); var navigationController = new UINavigationController(dialogViewController); View.Add (navigationController.View); 

et le dépotoir:

at (emballage géré à natif) MonoTouch.UIKit.UIApplication.UIApplicationMain (int, chaîne [], intptr, intptr) à MonoTouch.UIKit.UIApplication.Main (chaîne [], chaîne, chaîne) at MTD.Application.Main (ssortingng []) at (wrapper runtime-invoke) .runtime_invoke_void_object (object, intptr, intptr, intptr)

Stacktrace natif:

 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

Est-ce que je fais quelque chose de mal, ou est-ce un bug? Merci.

Évitez les modèles tels que:

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

car navigationController ne sera pas référencé (du côté géré ) une fois que l’appel View.Add est terminé et le ramasse-miettes peut en disposer (quand il le souhaite). Cependant, du côté natal , il devrait exister. Les appels retournant (de natif à géré ) vers l’instance supprimée planteront votre application.

Le bon modèle consiste à déclarer navigationController tant que champ (au lieu de variable locale) de votre type et à le créer / l’affecter dans la méthode. Cela gardera une référence à navigationController actif tant que l’instance parent existe (et garantira que tout rappel ne sera pas dirigé vers un object supprimé).

Par exemple

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