1

循環参照のためにコードがクラッシュしますか?

MenuController: UIViewController

- (id)initWithNibName:
{...
TabsController *tabs = [[TabsController alloc] initWithNibName:@"TabsController" bundle:nil];
self.tab = tabs;
....
}

//button pressed:
- (IBAction)showPrefFromMenu:(id)sender {
    // todo change delegate!?
     tab.tabDelegate = self;
    [self presentModalViewController:tab animated:YES];
    //[tab release];
}

// delegate method:
 -(void)myViewDismissed {
    .... 
    NSLog(@"tab references: %d", [tab retainCount]) ;

    [self dismissModalViewControllerAnimated:YES];//crash       
     ...

}

モーダル/子クラス:

TabsController : UIViewController <...>

- (IBAction)dismissTabs:(id)sender {
      ...
    NSLog(@"dismissTabs: sender: %@",sender);
    [self.tabDelegate myViewDismissed];    
}

私が見るように、self.tabDelegate は MenuController インスタンスであり、そのコードでは TabsController を閉じて割り当てを解除したいのです。

[self.tabDelegate myViewDismissed]; の後のコードではありませんが。しかし、割り当てが解除されているために実行できなかった場合は、おそらくアセンブリ Ret またはどの命令を実行できませんか? リターンステートメント。

デリゲートを分離しようとしますか、それともより良い解決策はありますか?

編集: クラッシュは典型的なものです: EXC_BAD_ACCESS(code=1,address=090) アセンブリは次のようになります: ldr r1, [r4, r0]

Edit2:シミュレーター4.3ではクラッシュしないため、コードを少し変更しましたが、5.0ではクラッシュします。現在のコードは次のとおりです。

- (IBAction)showTab:(id)sender {

    tab.tabDelegate = self;

    if (SYSTEM_VERSION_LESS_THAN(@"5.0")) {
        [self presentModalViewController:tab animated:YES];
    }
    else{
        NSLog(@"Executing presentViewController (ios>= 5.0)");
        [self presentViewController:tab animated:true completion: nil];
    }

}


 -(void)delegateCallback {

     if (SYSTEM_VERSION_LESS_THAN(@"5.0")) {
         [self dismissModalViewControllerAnimated:NO]; 
     }
     else{
         NSLog(@"Executing dismissViewControllerAnimated (ios>= 5.0)");
         [self dismissViewControllerAnimated:TRUE completion: nil];//crash
     }        

}

Edit3 スクリーンショット:

スレッド

UIWindowController transition:fromViewController:toViewController:didEndSeelctor 行が次の理由でクラッシュして ます。 issues/254ただし、NDA の下で

iOS 5.0+ 用の PushviewController に書き直すために解決された編集の heplfull リンク: https://stackoverflow.com/a/7767767/529543

- (IBAction)presentViewController:(id)sender {


    tab.tabDelegate = self;

    if (SYSTEM_VERSION_LESS_THAN(@"5.0")) {
        [self presentModalViewController:tab animated:FALSE];
    }
    else{
        NSLog(@"Executing presentViewController (ios>= 5.0) [tab retainCount]: %d " ,[tab retainCount]);       

    // store parent view to able to restore the state:
    parentView = self.view.superview;        

    // init a navigation controler and set up:
    navigationController=[[UINavigationController alloc] initWithRootViewController:self];                
    [self.view removeFromSuperview];

    [myAppDelegate.window addSubview:navigationController.view];   ///appDelegate is delegate of ur Application     

    navigationController.navigationBar.hidden =true;

    [navigationController pushViewController:tab animated:YES];       

}

}

そしてポップ:

-(void)infoViewDismissed {

     if (SYSTEM_VERSION_LESS_THAN(@"5.0")) {

         [self dismissModalViewControllerAnimated:NO];  
     }
     else{
         NSLog(@"Executing dismissViewControllerAnimated (ios>= 5.0) ");

         [navigationController popToRootViewControllerAnimated:false];        

         [navigationController.view removeFromSuperview];

         [parentView addSubview:self.view];

     }     
}

私は非常に醜いモードで私の問題を解決しましたが、機能しています...また、ios3のサポートを中止するように言われました:)実行時のGUIアーキテクチャの切り替えがまったく好きではありません。

4

2 に答える 2

3

あなたの質問は少しわかりにくいですが、保持サイクルがあると思います:

ObjectA retains ObjectB
ObjectB retains ObjectA

どちらのオブジェクトも割り当て解除されませんか?

tabDelegate のプロパティは次のようになります。

@property (nonatomic, assign) id tabDelegate;
//                    ^^^^^^-This is the important bit, this stops the retain cycle.
于 2012-08-06T17:32:20.320 に答える
1

詳細情報がないとわかりにくい(ARCを使用しているか、デリゲートを保持/割り当てているかなど)が、iOSドキュメントによると、非推奨のmodalviewメソッドも使用しています。試す価値があるかもしれません:

[self presentViewController:tab animated:YES completion:NULL];

[self dismissViewControllerAnimated:YES completion:NULL];
于 2012-08-06T17:47:02.460 に答える