8

今日からObjective-Cブロックを使い始めました。私は次のコードを書きました:

NSArray *array = @[@25, @"abc", @7.2];

void (^print)(NSUInteger index) = ^(NSUInteger index)
{
    NSLog(@"%@", array[index]);
};

for (int n = 0; n < 3; n++)
    print(n);

これは正しく機能します。ただし、宣言後に変数を変更する必要があったarrayため、次のコードを使用してみました。

NSArray *array;

void (^print)(NSUInteger index) = ^(NSUInteger index)
{
    NSLog(@"%@", array[index]);
};

array = @[@25, @"abc", @7.2];

for (int n = 0; n < 3; n++)
    print(n);

ただし、それは機能しません。コンソールは(null)3回だけ印刷します。私の最初のコードでは機能したのに、なぜこれが機能しないのですか?

4

2 に答える 2

21

これは、ブロックが値によって変数をキャプチャし、ブロックが作成されたときに(を使用しない限り__block)キャプチャするためです。

おそらく必要なものは次のとおりです。

NSArray *array = @[@25, @"abc", @7.2];

void (^print)(NSUInteger index) = ^(NSUInteger index)
{
    NSLog(@"%@", array[index]);
};

for (int n = 0; n < 3; n++)
    print(n);

__block

__block NSArray *array;

void (^print)(NSUInteger index) = ^(NSUInteger index)
{
    NSLog(@"%@", array[index]);
};

array = @[@25, @"abc", @7.2];

for (int n = 0; n < 3; n++)
    print(n);

__blockブロック内の変数を実際に変更して外部に反映させる必要がない場合は、使用するのが少し効率が悪いことに注意してください。

于 2012-10-12T16:50:27.980 に答える
3

arrayブロックは、作成時にポインターをキャプチャします。修飾子を追加__blockして、ブロックが参照によってポインターをキャプチャするようにすることができますが、これは通常コストがかかるため、お勧めしません。データをブロック内で使用する準備ができたら、キャプチャブロックを作成することをお勧めします。

于 2012-10-12T16:53:13.137 に答える