16

iOS 開発者にとって、デリゲートはほぼどこでも使用されます。

そして、このようなデリゲートには保持の代わりに「割り当て」を使用する必要があるようです

@property(assign) id delegate;

その理由は、循環ループの問題を回避するためです。Objective-C のデリゲートに通常、retain ではなく assign プロパティが与えられるのはなぜですか?

多くのコードを見ましたが、それらはまだ「保持」を使用していました。ここでの質問は、デリゲートに保持を使用すると、循環ループの問題が発生するかどうかです。

ありがとう

4

1 に答える 1

26

ドキュメントには次のように記載されています。

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

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

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

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

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

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

于 2011-03-03T03:45:18.233 に答える