block截获自动变量值
int number = 1;
void(^block)() = ^{
NSLog(@"number = %d",number);
};
number++;
block();
上面结果是1,原因就是block截获了自动变量值;到底是如何截获的呢?
根据block结构分析(见注释):
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
int number; //形成同名成员变量
//通过下面的构造函数中的numberValue(_number)把变量值保存到结构体中的同名成员变量number中
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _number, int flags=0) : numberValue(_number)
{
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
//取出同名的成员变量值
int number = __cself->number; // bound by copy
NSLog(@"number = %d",number);
}
static struct __main_block_desc_0 {
size_t reserved;
size_t Block_size;
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};
截获的变量只能使用不能修改,要想修改得加上__block;
//block截获的变量可以使用不能修改
- (IBAction)test_5id)sender {
NSMutableArray *mutArray = [[NSMutableArray alloc]init];
// 此block在栈上,不会对对象的引用计数产生影响
void(^block)() = ^{
#if 1
[mutArray addObject"hello - 1"];
[mutArray addObject"hello - 2"];
[mutArray addObject"hello - 3"];
#else
//被修改会报错,修改要在变量前加__block修饰
NSMutableArray *array = [[NSMutableArray alloc]initWithObjects"hello", nil];
mutArray = array;
#endif
};
block();
NSLog(@"count:%ld\n firstObject: %@",mutArray.count,mutArray.firstObject);
}
打印:
count:3
firstObject: hello - 1 |