6

__block 変数に関するドキュメントを読み、 __ block を使用するケースについて考えていました。私には、次の 2 つの場合に必要なようです。

  • ブロック内で変数を使用するときに読み書き可能としてマークするには
  • ブロック内で自分自身を参照するときにリテイン サイクルを回避するには

表面的には、これら 2 つのことは関連していないように見えます。__block 変数が保持されないという事実は、保持サイクルを回避するという特定のユースケースで覚えておく必要があるトリックの多くであると考えています。

それらを保持してはならない、より重要なアーキテクチャ上の理由があるのでしょうか? 上記の2つの機能を混同しないように、これを示す他のキーワードがより明確になると思います.

アップデート -

これは ARC を使用しないコードであることに注意してください。__block 変数が実際には ARC に保持されていることがわかりました。

4

1 に答える 1

12

__block手動参照カウントを使用する場合、変数は保持されません。理由はここにあります: http://www.mikeash.com/pyblog/friday-qa-2009-08-14-practical-blocks.html :

__blockこれに対する簡単な回避策は、変数が保持されないという事実にあります。これは、そのような変数が変更可能であり、それらの自動メモリ管理では、変更ごとに舞台裏でメモリ管理コードを生成する必要があるためです。これは、特に同じブロックが複数のスレッドから同時に実行される可能性があるため、非常に煩わしく、正しく処理するのが難しいと見なされていました。

また、ここ: http://lists.apple.com/archives/objc-language/2009/Dec/msg00100.html

変数内で値を再割り当てする際に保持カウントを適切かつ効率的に管理する方法はありません。

(Apple のドキュメントで「公式」のリファレンスを見つけることができませんでした。)

「ARC リリース ノートへの移行」に記載されているように、この動作は ARC で変更されました。

手動参照カウント モードで__block id x;は、 を保持しないという効果がありxます。ARC モードでは、__block id x;デフォルトで x を保持します (他のすべての値と同様)。ARC で手動参照カウント モードの動作を取得するには、 を使用できます__unsafe_unretained __block id x;。ただし、__unsafe_unretained という名前が示すように、非保持変数を持つことは (ぶら下がる可能性があるため) 危険であるため、推奨されません。より良い 2 つのオプションは、__weak(iOS 4 または OS X v10.6 をサポートする必要がない場合) を使用するか、保持サイクルを中断するために__block 値をに設定することです。nil

于 2013-06-29T21:38:34.580 に答える