2012-02-12 12 views
1

私は3ページの間をちょうどサイクルする小さなテストアプリを持っています。ここ はAppDelegateです:MonoTouch.Dialogクラッシュ

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; 

私は、ページからページへ移動することができ、各画面、すなわち上のボタンを配置した場合、私はしかしMonoTouch.Dialogを使用する場合、私はintermittenクラッシュを取得

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

。ここに私のコードは次のとおりです。

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

とダンプ:(管理ツーネイティブラッパー)MonoTouch.UIKit.UIApplication.UIApplicationMain(int型、文字列[]、のIntPtr、のIntPtr)<は0xffffffffで

> < 0x000b7> MTD.Application.MainでMonoTouch.UIKit.UIApplication.Main(文字列[]、文字列、文字列)(文字列[])(ラッパーランタイム呼び出し).runtime_invoke_void_objectで< 0x00017> (目的で、 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

私は何か間違っているのですか、これはバグですか?ありがとう。 navigationControllerが参照されることはありませんので、

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

View.Addコールが行われ、(それが望んでいる時はいつでも)ガベージコレクタはそれを配置することができたら(側の管理):

+0

「送信」SyledStringElementをタッチするとクラッシュするだけです。 – user1205691

答えて

0

のようなパターンを避けてください。しかし、ネイティブサイドからは、それが存在することが期待されます。破棄されたインスタンスに戻るコール(ネイティブから)がアプリケーションにクラッシュします。

正しいパターンは、タイプのフィールド(ローカル変数ではなく)としてnavigationControllerを宣言し、そのメソッドで作成/割り当てます。これにより、親インスタンスが存在する限り、navigationControllerへの参照が維持されます(また、コールバックが破棄されたオブジェクトに送られないようにします)。

など。

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

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

ありがとうございます。それは断続的なクラッシュを止めたようです。 – user1205691

+1

素晴らしいニュース:-) '、3などの行? 0xffffffff 0x0 + 4294967295'は、もはや存在しないインスタンスを指します(ネイティブフレームから呼び出されたときにはさらに多くなります)。 – poupou