私の現在のプロジェクトでは、いくつかのビュー コントローラー ( など)が、静的な NSOperationQueue で実行されるvc
NSOperation オブジェクト ( など) を生成します。operation
操作が待機中または実行中の場合、委譲 ( operation.delegate = vc
、割り当てられていない、保持されていない) を介してビュー コントローラーに報告されます。
ただし、これらの操作には時間がかかる場合があり、その間にアプリはビュー コントローラーの割り当てを解除できます (ナビゲーション コントローラーのスタックからポップすることにより)。
ここまではすべて意図的です。静的な NSOperationQueue を含むクラスには操作に戻る方法があるため、View Controller は操作を保持しません。それらは alloc/init/autoreleased であり、キューに入れられます。
現在、これも問題を引き起こしています。ビュー コントローラーの割り当てが解除された後、NSOperation の強力なデリゲートを呼び出すと、不正なアクセス違反が発生します。私が理解していることから、この質問に記載されているように、ポインターのオブジェクトが割り当て解除されているかどうかを確認することはできません。
私が考えることができる 1 つの修正は、操作を保持し、dealloc で operation.delegate を nil に設定することです。しかし、追跡するために多くの追加のivar /プロパティが導入されるため、それは私の最も人気のない修正です。
したがって、私の質問は、この問題を回避する他の方法はありますか? もしそうなら、ここにスケッチしていただけますか?
乾杯、
EP。
解決策:私にとって最もうまくいったアプローチは、ギリアーノの答えをわずかに変えたものでした:
キュー マネージャーにすべてのデリゲート プロトコルを実装することは現実的ではありません (50 以上のメソッドを持つ 20 以上の異なるプロトコル)。そのため、直接デリゲートの割り当てを維持しました。私が変更したのは、割り当て呼び出しを行うクラスです。これは、以前は要求を作成したクラス (およびデリゲート) でしたが、現在はキュー マネージャーにオフロードされています。
キュー マネージャーは、デリゲートを操作に割り当てるだけでなく、デリゲートと操作のペアを追跡するために、可変のセカンダリ ディクショナリも保持します。
すべてのデリゲート インスタンスは
[QueueManager invalidateDelegate:self]
割り当て解除時にメソッドを呼び出し、デリゲートに属するリクエストを検索して nil します。次に、ディクショナリ操作/デリゲートのペアも削除され、操作の適切な割り当て解除が可能になります。最後に、KVO
isFinished
が各操作のプロパティを監視することで、変更可能な dict がクリーンに保たれ、すべての操作保持カウントが終了後に実際に割り当て解除されるようになります。
これをクラックするために KVO を使用するためのヒントを提供してくれた Guiliano に感謝します!