为了能够保证block正常访问外部的变量,block有个变量捕获机制,如下图
auto:自动变量,平时我们定义int age = 10
,前面有个auto,auto int age = 10
,系统帮我们默认的加上了一个auto。—–值传递
—–
static:静态变量 —–指针传递
—–
全局变量 —–直接访问
—–
根据上面结论,我们一个个展开讨论和分析。
一、自动变量auto修饰的变量,auto int age = 10;
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
auto int age = 10;
void (^block)(void) = ^() {
NSLog(@"age = %d,",age);
};
age = 20;
block();
}
return 0;
}
此main函数中的block,是我们常见的OC代码,那我们从声明 int age = 10;
到将age的值改变age = 20
,最后block输出的age会等于20吗
带着这个疑问,我们来分析一下底层代码的实现,OC–>C++的转换过程:cd到程序main.m的目录下,执行命令xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m
,可以得到一个main.cpp文件,拖到工程目录中。
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
int age;
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _age, int flags=0) : age(_age) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
int age = __cself->age; // bound by copy