1

私のメイン アプリ コントローラーは、サブコントローラーを呼び出して、特定の一連の画面を処理します。メイン コントローラーは、サブコントローラーのデリゲートとして自分自身を設定します。サブコントローラーが処理を完了すると、デリゲートに通知します。時々、この通知は EXC_BAD_ACCESS で失敗します。

0) gdb に基づくと、objc_msgSend で問題が発生します。両方のレジスタにゼロ以外の値があります。

gdb: 0x3367cc98  <+0016>  ldr   r5, [r4, #8]

1) 問題を追跡するために NSZombiesEnabled を試しましたが、再現できませんでした。2)問題のあるコマンドの直前にブレークポイントを設定しようとしましたが、問題を再現できません。

何が起こっているのかわかりません。

これはデリゲート プロパティの宣言です (親コントローラーは子コントローラーよりも長生きします)。

@property (assign) id<ParentControllerDelegate> delegate

これは問題のあるコードです:

- (void) doStuff {
   if(mode == Done) {
     NSLog(@"Done. Handling back control");//this is the last log displayed by the console
     [self.delegate done: self];
   } else {
     // some controller code
}

これはデリゲート側のコードです (デリゲートはメイン コントローラーであるため、App_Delegate によって保持されています)。

- (void) done: (UIViewController *) caller {
   NSLog(@"Taken back control");// this never displays
   [caller.view removeFromSuperview];
   [caller release];
}

追加情報: メイン コントローラーはサブコントローラーを保持します。また、呼び出されたときにログに記録するように、メイン コントローラーとサブ コントローラーの両方の deallocs を変更しました。表示されているログに基づいて、どちらもアプリケーションの過程で呼び出されることはありません。したがって、メッセージの受信者と送信者の両方が有効なオブジェクトです。

私はここで本当に途方に暮れています。あなたの助けを楽しみにしています。

4

3 に答える 3

0

コードのように、呼び出しの前にプロトコルとメソッドのチェックを実行してみてください。

- (void) doStuff 
{
    if(mode == Done) 
    {
        NSLog(@"Done. Handling back control");//this is the last log displayed by the console
        if ([delegate conformsToProtocol: @protocol(ParentControllerDelegate)])
        {
            if ([delegate respondsToSelector: @selector(done:)] == YES)
            {
                [delegate performSelector: @selector(done:) withObject: self];            
            }
        }
    } 
    else 
    {
       // some controller code
于 2011-08-31T19:32:53.130 に答える
0

NSLog呼び出しが実行されない場合done:は、メイン コントローラーの を呼び出していないことを意味するだけですdone:。これは、有効でないことを意味するself.delegate場合があります。オブジェクトは有効で生きている可能性がありますが、self.delegateそれらの間のリンク ( ) はそうではありません。確認してください。の「doStuff完了」ブランチで、self.delegatewithのアドレスを表示します

NSLog(@"%p", self.delegate);

呼び出しdone:てメインコントローラーのアドレスと比較する前に。

于 2011-08-31T19:22:42.693 に答える
0

大雑把な推測ですが、「ときどき」の場合は、おそらくviewDidLoad後受信メモリ警告をviewDidUnload引き起こしている可能性があります。EXC_BAD_ACCESS特に前述のビューの読み込みメソッドで、親/子コントローラーで解放/保持/作成されたインスタンス変数を確認してください。

于 2011-08-31T19:16:38.320 に答える