2012-02-09 8 views
3

このシナリオでFirsViewControllerが破棄されない/解放された理由を理解できません。UINavigationControllerスタックからコントローラを削除します。

マイAppDelegate.m - FirstViewControllerがスタック

self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]]; 
self.navigationController = [[UINavigationController alloc]init]; 

self.FirstViewController = [[FirstViewController alloc] 
             initWithNibName:@"FirstViewController" 
             bundle:[NSBundle mainBundle]]; 
[self.navigationController FirstViewController animated:YES]; 

にプッシュされFirstViewController.m

self.SecondViewController = [[SecondViewController alloc] 
              initWithNibName:@"SecondViewController" 
              bundle:[NSBundle mainBundle]]; 
    self.SecondViewController.totalNumberOfPlayers = self.selectedRow; 
    [self.navigationController pushFadeViewController:self.SecondViewController]; 
    [self.view removeFromSuperview]; 

-(void)dealloc 
{ 
    [SecondViewController release]; 
    NSLog(@"SecondViewController released"); 
} 

Iは、第一から第2のビューコントローラにアプリとスイッチを実行すると何のNSLog入力がありませんコンソールで。これにより、最初のView Controllerは破棄されず、そのメモリは解放されないと私は思います。

このような状況で[self.view removeFromSuperview]のように表示されないようです。

私の質問は、FirstControllerをリリース/破棄する方法です。それは、アプリケーションの残りの部分で使用されることはありません。

答えて

16

スタック内のビューコントローラが解放/破棄されていないことは間違いありません。これはバグではありません。現在のビューコントローラをポップすると、元のビューコントローラを再度表示する必要があるため、設計通りです。あなたはそれをするつもりはないことをアプリは知りません。

あなたの[self.view removeFromSuperview]は、ビューコントローラをスタックからは削除していないので、ウィンドウからビューを削除するため動作しません。あなたのビューとView Controllerを混乱させる)。

あなたはあなたの2番目のビューコントローラをプッシュするとき、最初のビューコントローラを取り除きたい場合は、代わりに呼び出す:

[navigationController pushViewController:secondViewController animated:YES]; 

コールの代わりにこの:置き換えます

[navigationController setViewControllers:[NSArray arrayWithObject:secondViewController] animated:YES]; 

最初にコントローラを表示するだけではなく、新しいコントローラをその上に押し込むだけです。アニメーションは同じになります。

上記のメソッドを呼び出すと、最初のView Controllerがすぐに解放されるので、これを呼び出した後に最初のView Controllerに何もしないでください。クラッシュする可能性があります。

更新:それは

  1. プロパティにfirstViewControllerを保管しないでください、または:

    ここでアプリのデリゲートセットアップコードが見えるはずです方法は次のとおりです。注意すべき

    self.window = [[[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; 
    self.navigationController = [[[UINavigationController alloc] init] autorelease]; 
    
    FirstViewController *firstViewController = [[FirstViewController alloc] init]; 
    [self.navigationController pushViewController:firstViewController animated:YES]; 
    [firstViewController release]; 
    

    物事それがポップされ、deallocが呼び出されることはありません(あなたはfirstViewControllerを削除することができます)プロパティがリリースされません。変数名の

  2. 使用小文字、唯一のクラス名

  3. を大文字に、必ずあなたがそれらを作成するのと同じ方法で/ initのをアロケーションオブジェクトを解放または自動解放 - これはアナライザの警告を回避(およびリークを防ぐ)になります。

  4. nibファイル名がView Controllerクラス名と一致する場合は、nibファイルを指定する必要はありません。

ニック

+0

おかげで、ニック! 私には2つの質問があります。あなたが提案したコードを試しましたが、最初のView Controllerのdeallocメソッドは呼び出されません。また、そのコードを順番に使用できますか?私が使用することを意味する[navigationController setViewControllers:[NSArray arrayWithObject:thirdViewController] animated:YES]; theSecondViewControllerの[navigationController setViewControllers:[NSArray arrayWithObject:fourthViewController] animated:YES]; 3番目のビューコントローラなど – Profo

+0

完了したらself.FirstViewControllerプロパティをnilに設定する必要があります。それ以外の場合は解放されません。 setViewControllers:メソッドを好きなだけ何度でも使用できますが、pushViewController:を使用して次のビューを表示しない限り、popViewController:メソッドを使用して前のビューに戻ることはできません。 –

+0

私は実際には、FirstViewControllerをプロパティに格納しないことをお勧めします。関数内でローカル変数を使用して作成し、ナビゲーションコントローラにプッシュし、ローカル変数を解放します。 navigationControllerはそれが表示されている間はそれを保持しているので、アプリケーションデリゲートのプロパティに格納する必要はありません。 –

関連する問題