web-dev-qa-db-ja.com

デリゲートのプロパティ「assign」と「retain」

IOS開発者の場合、デリゲートはほとんどどこでも使用されます。

そして、このような代理人のために保持する代わりに「割り当て」を使用する必要があるようです

@property(assign) id delegate;

理由は、循環ループの問題を回避するためです Objective-Cデリゲートが通常、保持ではなくプロパティの割り当てを与えられるのはなぜですか?

私はたくさんのコードを見ました、そして彼らはまだ「保持」を使用しました。したがって、ここでの質問は、デリゲートにretainを使用した場合でも、循環ループの問題が発生するかどうかです。

ありがとう

16
Forrest

ドキュメント は言う:

オブジェクトを保持すると強力な参照が作成され、すべての強力な参照が解放されるまでオブジェクトの割り当てを解除することはできません。 2つのオブジェクトが相互に保持している場合、オブジェクト間の接続を切断できないため、どちらのオブジェクトも割り当てが解除されることはありません。

例として、UITableViewDelegateプロトコルを実装するUITableViewControllerについて考えてみましょう。 UITableViewはそのデリゲートを保持しませんが、そのビューコントローラによって保持されます。

上記のドキュメントで述べたように、UITableViewControllerは、すべての強力な参照が解放されたときにのみ割り当て解除を完了します。 UItableViewControllerをデリゲートとして持つUITableViewはそれを保持しないため、UItableViewControllerの所有者がreleaseを呼び出すと、保持カウントがゼロになり、deallocメソッドが呼び出されます。

ここで、UITableViewがそのデリゲートを保持していると想像してください。 UITableViewControllerの保持カウントは少なくとも+2になります。 1つは所有者で、もう1つはUITableViewです。 UITableViewControllerの所有者がリリースを呼び出すと、保持カウントは+1になり、予想どおりゼロにはなりません。そのため、保持カウントがゼロに達するまで、deallocメソッドは呼び出されません。ゼロに到達するには、UITableViewControllerはUITableViewを解放する必要があり、UITableViewはデリゲート(UITableViewController)を解放します。 UITableViewControllerは、保持カウントが+1を下回らないため、この瞬間の割り当て解除が発生しない場合にのみビュー(UITableView)を破棄するためです。

(メモリの警告やその他の考えられるケースを考慮しないでください...この例ではViewController/Viewが最適なオプションではないことがわかりましたが、すでに書きすぎています。:))

それは理にかなっていますか?

26
vfn