1

iOS 6アプリには、デフォルトの通知センターでオブザーバーとして追加されるいくつかのビューコントローラーがあります。viewDidLoadこれらは、コントローラーが最上位にない場合でも通知を受信するようにするため、メソッドに追加されます。

多くの人が、deallocメソッドでオブザーバーを削除することを推奨しています。NSLog()ただし、オブザーバーを追加および削除するときに両方でメッセージをログに記録しており、dealloc呼び出されないようです(ARCを使用しています)。

考えられることとは反対に、このviewDidUnloadメソッドはオプションではありません。iOS5ではメモリ不足の状態でのみ呼び出され、iOS6ではまったく呼び出されないためです。

実際には、ドキュメントに必要なことを行う方法はないようです。ちなみに、これまでのところ、コントローラーが複数回追加され、(明らかに)削除されていないにもかかわらず、私のアプリケーションはクラッシュしていません。

注:これまでのところ、私はシミュレーターのみでテストしてきました。deallocシミュレーターではなく、実際のデバイスで呼び出される可能性はありますか?NSLog()または、単に表示されないという呼び出しです(ただし、他のすべての場所に表示されます)。

4

2 に答える 2

3

アークでも、deallocが呼び出されます。アークで[superdealloc]を呼び出すことはできませんが、ViewControllerが解放されている場合はdeallocを呼び出す必要があります。ただし、管理が非常に難しい場合は、通知オブザーバーをviewWillAppearに追加してから、viewWillDisappearで削除しないでください。そうすれば、ビューが表示されるまで通知を受け取ります。ビューが表示されていない間は解放される可能性があるため、viewWillDisappearでオブザーバーを削除する必要はありません。しかし、確かに十分なdeallocが呼び出され、これに適した場所です。

于 2012-11-27T22:49:49.773 に答える
0

@NSProxyは正しかったdeallocので、呼び出す必要があります。しかし、それは私のコントローラーのいくつかのために呼び出されていませんでした。理由は次のとおりです。

ビューコントローラーAはコントローラーBにセグエしていました。ではprepareForSegue、コントローラーAは、コントローラーB(ターゲットコントローラー)への参照を含むブロックを作成していました。ブロックがコントローラーA(ホームコントローラーである)によって保持され、ブロックがBに保持されていたため、コントローラーBの割り当てが解除されることはありませんでした。

ブロック内のBへの参照を弱いポインターに変更し、Bのビューが消えたときにvoilàが呼び出されましたdealloc物語の教訓は、周りにとどまっているクラスに属するブロックで参照するものに非常に注意する必要があるということです。

これでも1つの謎が残りますdealloc。ホームボタンをクリックしたり、シミュレーターでアプリを停止したりしてアプリを終了した場合でも、ホームコントローラーが呼び出されない理由がわかりません。ホームコントローラーを参照するブロックはないため、どこかにコントローラーを保持している他の何かが存在する必要があります。

于 2012-11-28T22:34:41.547 に答える