Effective Objective-C 2.0 笔记6
六、Blocks和GCD
①、block是在用栈上的内存来定义的。意思是只有在它的定义的作用域内,block才是有效的。
例如,下面的代码就是错误的:1
2
3
4
5
6
7
8
9
10
11void(^block)();
if(/*some condition*/) {
block = ^{
NSLog(@"Block A");
};
} else {
block = ^{
NSLog(@"Block B");
};
}
block();
两个block在if-else域内都是用栈内存定义的。当对每个block进行申请内存操作,就会重写覆盖在作用域结尾处申请的内存。所以,只有在每个if-else模块内,block才能确保是正确的。这个代码可以编译成功,但是在运行时,可能会出现错误。因为无法确定执行的是哪个block。
为了解决这个问题,可以向block发送copy消息,block就会从栈(stack)复制到堆(heap)上。此时,block就可以在它定义的作用域外面使用。block也会变成为一个引用计数的对象。所以上面的代码例子,修改一下,就变为正确了。1
2
3
4
5
6
7
8
9
10
11void(^block)();
if(/*some condition*/) {
block = [^{
NSLog(@"Block A");
} copy];
} else {
block = [^{
NSLog(@"Block B");
} copy];
}
block();