アプリを ARC に変換したところ、View Controller の 1 つで割り当てられたオブジェクトが、その View Controller が割り当て解除されたときに割り当て解除されていないことに気付きました。理由を理解するのにしばらく時間がかかりました。デバッグ中にプロジェクトのゾンビ オブジェクトを有効にしましたが、これが原因であることが判明しました。次のアプリ ロジックを検討してください。
1) ユーザーは、を介して を作成および提示するRootViewController
アクションを呼び出します。SecondaryViewController
presentModalViewController:animated
2)サブクラスである がSecondaryViewController
含まれています。ActionsController
NSObject
3)初期化されたときにActionsController
通知を監視し、NSNotificationCenter
割り当てが解除されたときに監視を停止します。
4) ユーザーは終了SecondaryViewController
して に戻りRootViewController
ます。
Enable Zombie Objects をオフにすると、上記は正常に機能し、すべてのオブジェクトの割り当てが解除されます。Enable Zombie Objects をオンにすると、割り当てが解除されActionsController
ても、割り当てSecondaryViewController
が解除されません。
これにより、アプリで問題が発生し、b/cNSNotificationCenter
が通知を送信し続けActionsController
、結果のハンドラーによってアプリがクラッシュします。
これを示す簡単なアプリをhttps://github.com/xjones/XJARCTestAppで作成しました。これを確認するには、[ゾンビ オブジェクトを有効にする] をオンまたはオフにしてコンソール ログを調べます。
質問
- Enable Zombie Objects のこの動作は正しいですか?
- 問題を解決するには、このタイプのロジックをどのように実装すればよいですか。Enable Zombie Objects を引き続き使用したいと思います。
編集 #1: Kevin の提案に従って、これを Apple と openradar ( http://openradar.appspot.com/10537635 ) に提出しました。
編集#2:良い答えの明確化
まず、私は経験豊富な iOS 開発者であり、ARC やゾンビ オブジェクトなどを完全に理解しています。
次に、この特定のクラッシュの回避策は、割り当てが解除actionsController
されたときにオブザーバーとして削除することsecondaryViewController
です。また、いつ解放されるかを明示的に設定actionsController = nil
するsecondaryViewController
と、解放されることもわかりました。これらはどちらも優れた回避策ではありません。実際には ARC を使用する必要がありますが、ARC を使用していないかのようにコーディングします (dealloc で iVar を明示的に nil にするなど)。特定の解決策は、これが他のコントローラーの問題になる時期を特定するのにも役立ちません。したがって、開発者は、この問題を回避する時期と方法を決定論的に知ることができます。
良い答えは、ARC + NSZombieEnabled を使用するときにオブジェクトに対して何か特別なことをする必要があることを決定論的に知る方法を説明し、この特定の例を解決し、他の同様の可能性を残さずにプロジェクト全体に一般的に適用することです問題。
これは XCode のバグである可能性があるため、適切な答えが存在しない可能性は十分にあります。
皆さんありがとう!