[objective-c] "__block"キーワードは何を意味しますか?


2 Answers

@bbumは、 ブログ投稿のブロックを詳細にカバーし、__blockストレージタイプを扱います。

__blockは異なるストレージタイプです

静的、自動、および揮発性と同様、__blockはストレージタイプです。 これは、変数の記憶域を別々に管理することをコンパイラに指示します。

...

ただし、__block変数の場合、ブロックは保持されません。 必要に応じて、あなたが保持し解放するのはあなた次第です。
...

ユースケースについては、 __blockは引数を保持しないため保持サイクルを避けるために使用されることがあります。 一般的な例として、selfを使用します。

//Now using myself inside a block will not 
//retain the value therefore breaking a
//possible retain cycle.
__block id myself = self;
Question

Objective-Cの__blockキーワードとはどういう意味ですか? 私はあなたがブロック内の変数を変更することができることを知っていますが、私は知りたいです...

  1. それはコンパイラに正確に何を伝えていますか?
  2. それは他の何かをしますか?
  3. それがすべてであれば、最初はなぜ必要なのでしょうか?
  4. どこにいてもドキュメントにありますか? (私はそれを見つけることができません)。



__blockは、スコープ変数を変更可能にするために使用する記憶域型です。この指定子で変数を宣言すると、その参照は読み取り専用コピーではなくブロックに渡されます。詳しくは、iOSのブロックプログラミングを参照してください。




ブロック言語仕様から

新しいブロックタイプに加えて、ローカル変数のための新しいストレージ修飾子__blockも導入されています。 [testme:ブロックリテラル内の__block宣言] __blockストレージ修飾子は、既存のローカルストレージ修飾子auto、register、およびstaticと相互に排他的です。[testme] __blockで修飾された変数は、割り当てられたストレージ内にあるかのように動作し、前記変数の最後の使用後に自動的に回復される。 実装は、ストレージが最初は自動であり、参照ブロックのBlock_copy時に割り当てられた(ヒープ)ストレージにのみ移動する最適化を選択することができます。 このような変数は、通常の変数と同様に突然変異してもよい。

__block変数がブロックである場合、__block変数は割り当てられた記憶域にあると仮定し、割り当てられた記憶域にもある(Block_copy操作の結果である)ブロックを参照すると見なされます。 それにもかかわらず、インプリメンテーションがブロックの初期自動ストレージを提供する場合、Block_copyまたはBlock_releaseを行う規定はありません。 これは、シェア変数を更新しようとする潜在的な複数のスレッドの固有の競合状態と、古い値を破棄して新しい値をコピーするための同期の必要性が原因です。 このような同期は、この言語仕様の範囲外です。

__block変数のコンパイル方法の詳細については、 ブロック実装仕様の 2.3節を参照してください。




Related