0

ここでブロック保持サイクルを防ぐための解決策を見ました

しかし、なぜ、またはどのように機能するのかについて頭を悩ますのに苦労しています。

この例では、弱い自己参照が作成され、実行されます。これがどのようにサイクルを壊すかがわかります。ただし、ブロック内で強い参照が作成されます。これは、最初に防止しようとしていたリテイン サイクルを再現するのではないでしょうか?

たとえば、self が 0x123 の場合、weakself も 0x123 を指しています。次に、strongSelf はブロック内で 0x123 に設定されます。
これは保持サイクルになりませんか? (self は block への強い参照を持ち、strongSelf は self への強い参照を持ちます)

4

2 に答える 2

1

ブロック内で強い参照が作成されます。これは、最初に防止しようとしていたリテイン サイクルを再現するのではないでしょうか?

はい、そうですが、一時的なものです。がstrongSelf初期化されると、現在のweakSelf値への強力な参照が形成されます。(または、オブジェクトの割り当てが解除されている場合は nil。) ブロックの実行が終了すると、この (ローカルの) 強い参照が解放され、サイクルが中断されます。

問題は保持サイクル自体ではなく (常に発生します)、オブジェクトを予想よりも長く存続させる長寿命の保持サイクルです。

于 2014-07-07T20:47:39.280 に答える
1

たとえば、self が 0x123 の場合、weakself も 0x123 を指しています。次に、strongSelf はブロック内で 0x123 に設定されます。これは保持サイクルになりませんか?

実は違う; それらはすべて同じものを直接指し示しているわけではありません。実際には、ARC の弱参照は実際に (舞台裏で) 追加のオブジェクトをミックスに挿入します。これをスクラッチパッド オブジェクトと呼びましょう。同じオブジェクトを指しているように見えますが、実際にはスクラッチパッド オブジェクトを指しいるため、指しているものが保持されません。これが ARC の弱参照の仕組みです (弱参照のゼロ化とも呼ばれます)。それらは、それ自体を保持せずに保持できる特別な追加のスクラッチパッドオブジェクトを含み、チェーンを壊します。

リテイン サイクルでは、A は B にリテインを持ち、B は A にリテインを持っていdeallocます。

ブロックの状況では、A がブロックでself、B がブロックです。self何らかの理由でブロックに保持を設定します (多くの場合、コピーやオブザーバーなどに関係してかなりあいまいです。常に発生するとは限りません。実際、ほとんどの人が考えているよりもはるかにまれに発生します)。 . selfブロックは、それがクロージャーであり、ブロック内で参照されているという事実だけで保持されselfます。

しかし、弱強のダンスをすることで、これを防ぎます。ブロックに渡されるのはweakself、実際にはスクラッチパッド オブジェクトを介した参照です。ブロックはこれを保持できますが、保持しませんself。したがって、保持サイクルはありません。

于 2014-07-07T20:36:44.040 に答える