变量捕获capture
局部变量
-(void)testBlock {
int age = 10;
void(^blcok)(void) = ^(void){
NSLog(@"block - %d",age);
};
age = 20;
blcok();
}
- 打印
10
根据大神贴出的源码,其实底层C++代码就是将age作为参数传递,仅仅传递的是age的值,所以是值传递
__block修饰
-(void)testBlock {
__block int age = 10;
void(^blcok)(void) = ^(void){
NSLog(@"block - %d",age);
};
age = 20;
blcok();
}
- 打印
20
C++源码中,是以&age形式传递参数的,因此是地址传递
auto __block static
-(void)testBlock {
auto int weight = 1;
__block int age = 2;
static int height = 3;
void(^blcok)(void) = ^(void){
NSLog(@"block: weight - %d , age - %d, height - %d",weight,age,height);
};
weight = 10;
age = 20;
height = 30;
blcok();
}
- 打印
block: weight - 1 , age - 20, height - 30
auto 默认的局部变量修饰关键字 局部变量是以值作为参数传递的,__block和static修饰的变量是以指针形式作为参数传递的
全局变量
int ageGlobal = 1;
static int heightGlobal = 2;
-(void)testBlock {
void(^blcok)(void) = ^(void){
NSLog(@"block: ageGlobal - %d , heightGlobal - %d",ageGlobal,heightGlobal);
};
ageGlobal = 10;
heightGlobal = 20;
blcok();
}
- 打印
block: ageGlobal - 10 , heightGlobal - 20
全局变量在C++底层代码中都是直接访问的,并不是以值传递或者指针传递的
特殊情形
-(void)testBlock {
void(^blcok)(void) = ^(void){
NSLog(@"%@",self);
};
blcok();
}
如上代码,self也是变量捕获,如下代码oc中每个函数都有默认的两个参数,既然作为参数也就是局部变量,因此也就会被捕获
-(void)testBlock(self,(SEL)sel) {
}
总结
- 局部变量会被捕获,是以值作为参数传递的
- 全局变量不会被捕获,是以直接访问的形式获取值的
- static和__block 修饰的都是指针形式传递的