Objective C: 块变量只能使用一次吗?

Objective C: Can a block variable be used only once?

假设我需要多个块 "calls",例如在每次迭代中将块传递给另一个函数的循环。我是否需要在每次调用函数时都创建一个新的块实例(如示例 1),或者我是否可以创建一个每次调用的块实例(如示例 2)?

//Example 1:
while(true){
    void (^block)(NSString* test)=^(NSString* test){
        //do something
    };
    [self callWithBlock: block];
}

//Example 2
void (^block)(NSString* test)=^(NSString* test){
    //do something
};
while(true){

    [self callWithBlock: block];
}

第二种方式编译和运行良好,但我怀疑任何并发问题可能不会立即显而易见。

您可以根据需要随时调用块。但是你需要注意块捕获的上下文。

如果您的块捕获了任何值,请记住,除非将它们指定为 __block 变量,否则它们将被复制。

例如,这段代码:

int anInteger = 42;

void (^testBlock)(void) = ^{
    NSLog(@"Integer is: %i", anInteger);
};

anInteger = 84;

testBlock();

将打印 42,而不是 84。

如果将 anInteger 声明为 __block int anInteger = 42,存储将被共享,代码将打印 84。

因此,如果您的代码类似于:

int foo = 42;

void (^block)(void) = ^{
    NSLog(@"%i", foo);
}
while (true) {
    block();
    foo++;
}

行为将不同于

int foo = 42;
while (true) {
    void (^block)(void) = ^{
        NSLog(@"%i", foo);
    }
    block();
    foo++;
}

当您重新分配保存指针或对象的变量时,这也适用于指针和 NSObject 变量。

要了解更多信息,请查看 Apple 开发人员文档中的 Working with Blocks