2009-08-22 15 views
2

私のiPhoneアプリケーションでは、次の方法で表示される「統計」ビューがあります。メソッド自体は、ユーザーがボタンに触れると呼び出されます。この方法は、統計においてUINavigationControllerObjective-C/iPhoneのメモリ管理

- (void) showStatsView { 
    StatsViewController *statsViewController = [[StatsViewController alloc] initWithNibName:@"Stats" bundle:[NSBundle mainBundle]]; 
    [self pushViewController:statsViewController animated:YES]; 
    [statsViewController release]; //      (1) 
} 

自体を視聴中NSDictionary、「statsDict」で使用されています。次のオプションを持つプロパティとして宣言されています:(非原子的、保持)。私StatsViewControllerで

viewDidLoad方法はそうのようなNSDictionaryのインスタンスを作成します。私はリロードしようとすると、私の問題が発生した

- (void)dealloc { 

    /* 
    dealloc'ing other stuff here which is irrelavent 
    */ 
    [statsDict release]; //     (2) 
    [super dealloc]; 
} 

:ようStatsViewControllerため

MyAppDelegate *appDelegate= (MyAppDelegate *)[[UIApplication sharedApplication] delegate]; 
stats = [[NSDictionary alloc] initWithContentsOfFile:[appDelegate statsFilePath]]; 

私のdeallocメソッドが見えます統計ビューは一度表示された後に表示されます。つまり、showStatsViewを起動させるボタンを押します。統計ビューが読み込まれ、現在はすべて正常です。

統計ビューのボタンを押してメインメニューに戻ります(これは[self popToViewController:MainMenuViewController];を使用するメソッドを呼び出して行います)。ここから、統計ビューを再度ロードするボタンを押した場合(2回目)、私のアプリはEXC_BAD_ACCESSでクラッシュします。

showStatsViewで(1)とマークされた行を削除すると、deallocで(2)とマークされた行を削除した場合と同様に正常に動作します。しかし、私が読んだところでは、statsDictを私はそれを割り当てたようにリリースしなければなりません、同様に、私はそれを割り当てたので、statsViewControllerをリリースするべきです。しかし、もし私が両方をすれば - それはクラッシュします!私は何をすべきか?

私は客観的なメモリ管理の理解にいくつかのステップを逃したことがありますか?

+0

[appDelegate statsFilePath]の実装を投稿できますか? –

+0

ここでstatsDictを設定しますか?私は "stats"を参照してください – newacct

+0

stats/statsDict混乱をクリアしてください。それはタイプミスですか?誤って辞書の代わりにいくつかのivarに辞書を割り当てていますか? – VoidPointer

答えて

1

(1)または(2)を削除したときにアプリがクラッシュしない理由は、両方が辞書を意図的に漏らしているということです(ポイント2では辞書を漏らしてポイント1でリーク辞書の所有者であるので、-deallocは呼び出されません)。明らかに、それはあなたがしたいことではありません。契約の理解は正しいですが、私はあなたのオブジェクトがどのように初期化されているのか誤解していると思います。

あなたはここにあなたのコードを再現しませんでしたが、推測すると、ここでの問題は、ビューがアーカイブされていないと-viewDidLoadが一度しか呼び出されないことです。したがって、その後のstatsViewControllerの作成では、辞書は割り当てられません。

NSDictionaryを-viewDidLoadからstatsViewControllerの-initメソッドに割り当てる行を移動すると、意図的にオブジェクトをリークさせることなくすべて正常に動作します。新しいstatsViewControllerを作成するたびに呼び出されます。 -initメソッドがない場合は、作成します([super init]を呼び出すことを忘れないでください)。

幸運のベスト。

+0

'viewDidLoad'と' init'の良い点です。しかし、 'viewDidLoad'は複数回呼び出されることに注意してください(たとえば、ビューが表示されず、コントローラが' didReceiveMemoryWarning'メッセージを受け取った場合、ビューはアンロードされ、後でビューを再度ロードする必要があります)。 peterbが述べたように、 'statsDict'をビューコントローラのすべてのインスタンスに対して一度初期化するのは' init'で行うのが一番です。 – Tim

+0

StatsViewControllerがinitWithNibNameでNIBからフリーズされているときのAFAIK。オブジェクトに送信されるinitメッセージはありません。 – VoidPointer

+0

可能であれば、StatsViewController _がdealloced_されています。これは、-deallocメソッドが実行されているためにわかります。したがって、後続のStatsViewControllerが作成されたときに、その辞書を再初期化する必要があります。 – peterb

2

契約の理解が正しいように見えます(「statsDict =」とは「stats =」と言っています)。

他のどこかで問題が発生している可能性があります。おそらく他の場所で契約が破られている可能性があります。

環境変数NSZombieEnabledNSAutoreleaseFreedObjectCheckEnabledを使ってメモリデバッグを有効にして、どのオブジェクトが解放されているかを確認することをお勧めします。

+0

+1 for NSZombieEnabled - 割り当て解除されたオブジェクトへの呼び出しを見つけるのに非常に役立ちます。 – Tim