2013-06-29 18 views
6

私は__block variablesのドキュメントを読んでいて、__blockを使用している場合について考えていました。私にとって、私が2つの場合に、それを必要とするように思える:__block変数が保持されないのはなぜですか(非ARC環境の場合)?

  • は、読み書きなどの変数をマークするにはブロック内で自己を参照するときにサイクルを維持避けるためにブロック
  • 内で使用する場合

表面には、これら2つのものが関連しているようには見えません。私は、__block変数が、保持サイクルを避ける特定の使用例について覚えておく必要があるより多くのトリックとして保持されないという事実を考慮します。

なぜ、それらを保持してはいけないのか、より重要な、建築上の理由はありますか?上記の2つの機能を混在させないように、これを明確にするためのキーワードがあると思います。

更新 -

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

+2

最初のものにのみ '__block'を使用します。保持サイクルを避けるために '__block'ではなく' __weak'を使います。 – rmaddy

+2

また、__block変数が保持されないという考えをどこから得ましたか? ARCは通常の変数と同様に自動的にそれらを保持します。 –

+2

ARCの前に、__block変数は実際に保持サイクルを回避するためのメカニズムとして保持されていませんでした。それはARCによって変更され、「ARCリリースノートへの移行」に記載されています。 –

答えて

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

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

(。私はアップルのドキュメントの「公式」の参照を見つけることができませんでした)

"Transitioning to ARC Release Notes"に記載されているように、この動作は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に設定して保持サイクルを中断することです。

+0

ニース、それは理にかなっています。ありがとう。 –

+0

@darren:これらの参照をもう一度読んだら、保持サイクルを避けることは、__block変数の設計目標よりも副作用が多いようです。 –

関連する問題