2017-02-19 4 views
0

セイ・マップはNSDictioanryですが、resのアドレスはブロック内で変更されないので、__blockを使用する必要はありません。これは正しいです?ブロック単位で変更可能な可変オブジェクトの__block型指定子を使用する必要がありますか?

//__block NSMutableArray *res = [@[] mutableCopy]; 
NSMutableArray *res = [@[] mutableCopy]; 
__block NSInteger i = 0; 
[map enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSArray *v, BOOL *stop) { 
    [res addObject:v]; 
    i++; 
}]; 

ところで、私はコードを実行していますが、うまくいきます。

+0

コンパイラは文句を言っていますか?コードを実行して 'res'を表示してください。何が起こるのですか? – vadian

+0

私はそれを正常に動作しました – user3315620

+0

答えは:いいえ:-) '__block'がない場合、コンパイラはあなたに通知します。 – vadian

答えて

2

__blockタイプ指定子は、通常はスタックに入る可変アイテムの格納にのみ必要です。

ブロックは、それを作成するメソッドのスコープ内でのみ呼び出されることが保証されていないので(エスケープと呼ばれます)、ブロックされた後に参照する変数を変更する必要があります。スタック上にあるもの(例えば、あなたの例ではiのようなもの)への参照は、元のメソッドや関数の終わりを過ぎてもブロックが保持されているとぶら下がってしまう可能性があります。したがって、それらを変更する場合は、スタックよりも。 __block指定子は、ブロックが呼び出されるたびに有効な別の記憶域に変数を格納するようにコンパイラに指示します。

ヒープ割り当てされたもの(上記のresのようなもの)の場合、オブジェクトへのポインタはオブジェクトが周囲にいる限り変更されないため、これは必須ではありません(ブロックする必要があります。デフォルト)では、オブジェクトポインタのローカルストレージを別のストレージに配置する必要はなく、スタック上に置くことができます。

Blocks and Variablesのドキュメントページには、ブロックを使用したメモリ管理の詳細情報があり、__blockのストレージタイプについて詳しく説明しています。

0

これは間違いありません。 __blockは、ブロック内の変数に(=または同等の)を割り当てる場合、またはブロックの作成後にブロック外の変数への代入を参照できるようにブロックする場合にのみ必要です。 (これは変数の型に関係なく当てはまります。)++演算子を使用して変数iがブロック内部に割り当てられます。したがって__blockが必要です。変数resはどこにも割り当てられません。変数resはブロック内でから読み取られたです(割り当てられていません)。

関連する問題