アプリを ARC に変換したところ、View Controller の 1 つで割り当てられたオブジェクトが、その View Controller が割り当て解除されたときに割り当て解除されていないことに気付きました。理由を理解するのにしばらく時間がかかりました。デバッグ中にプロジェクトのゾンビ オブジェクトを有効にしましたが、これが原因であることが判明しました。次のアプリ ロジックを検討してください。
1) ユーザーは、を介して を作成および提示するRootViewControllerアクションを呼び出します。SecondaryViewControllerpresentModalViewController:animated
2)サブクラスである がSecondaryViewController含まれています。ActionsControllerNSObject
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 のバグである可能性があるため、適切な答えが存在しない可能性は十分にあります。
皆さんありがとう!