Blocks(二)

在Blocks(一)中简单介绍了下Block的基本语法,解释了“带有自动变量值的匿名函数”中的“匿名函数”,下面来说一说“带有自动变量值”。“带有自动变量值”在Blocks中表现为“截获自动变量值”。看这个例子:

int main(){
    int val = 10;
    void (^blk) (void) = ^{printf(“val = %d\n,val”);};
    val = 2;
    blk();
    return 0;
}

在这段代码中,Block使用的是它之前声明的自动变量val。Block表达式截获所使用的自动变量的值,即保存自动变量的瞬间值。因为Block保存了自动变量的值,所以在执行Block后,即使改写Block中使用的自动变量的值也不会影响Block执行时自动变量的值。因此结果为val = 10,而并不是2。
再来下面这段代码;

int val = 0;
void (^blk) (void) = ^{val = 1;};
blk();
printf("val  = %d\n",val};

这段代码在编译时就会发生错误,这是因为自动变量值截获只能保存执行Block语法瞬间的值,保存后就不能改写。但是我们也可以在Block中修改在Block语法外声明的自动变量,只要在该自动变量前面加上__block说明符:

__block int val = 0;
void (^blk) (void) = ^{val = 1;};
blk();
printf("val = %d\n",val);

运行结果为val = 1。
那么截获Objective-C对象呢?

id array = [[NSMutableArray alloc] init];
void (^blk) (void) = ^{
    id obj = [[NSObject alloc] init];
    [array addObject:obj];
}

运行后我们发现并没有问题,在这段代码中,截获的NSMutableArray类的对象。换成C语言的说法,即是截获NSMutableArray类对象用的结构体实例指针。虽然赋值给截获的自动变量array的操作会产生编译错误,但是使用截获的值不会有任何问题。
未完待续

你可能感兴趣的:(Blocks(二))