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

时间:2019-05-17 21:25:48

标签: objective-c objective-c-blocks

假设我需要多个块“调用”,例如一个循环,其中该循环在每次迭代中都传递给另一个函数。每次调用该函数时都需要创建一个新的块实例(如示例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];
}

它可以通过第二种方式编译并正常运行,但是我怀疑并发问题可能不会立即显现。

1 个答案:

答案 0 :(得分:4)

您可以根据需要多次调用块。但是您需要注意该块捕获的上下文。

如果您的块捕获了任何值,请记住,除非将它们指定为__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