概要
什么是Blocks
是带有自动变量(局部变量)的匿名函数
C++ 和 Object-C 使用类可保持变量值且能够多次持有该变量本身,Blocks 提供了类似类生成实例或对象来保持变量值的方法
模式
语法
//完整形式
^void (int event){
printf("buttonId: %d event = %d\n", i, event);
}
//^ 返回值类型(可省略) 参数列表(可省略) 表达式
//^(int count){return count + 1;}
//^{printf("kk");}
Block 类型变量
//函数指针
int func(int count){
return count + 1;
}
int (*funcptr)(int) = &func;
//Block 类型变量
int (^blk)(int);
Block 类型变量与一般 C 语言变量完全相同,可作为自动变量/函数参数/静态变量/静态全局变量/全局变量使用。
//赋值
int (^blk)(int) = ^(int count){return count + 1;}
int (^blk1)(int) = blk;
int (^blk2)(int);
blk2 = blk;
//作为函数参数
void func(int (^blk)(int)){}
//作为函数返回值
int (^func()(int)){
return ^(int count){return count + 1;};
}
//使用typedef简化
typedef int (^blk_t)(int);
void func(blk_t blk){};
blk_t func(){};
调用:
//函数
int result = (*funcptr)(10);
//Block
int result = blk(10);
//作为函数参数调用
int func(blk_t blk, int rate){
return blk(rate);
}
//Block指针类型变量
blk_t blk = ^(int count){return count + 1;};
blk_t *blkptr = &blk; //似乎不可以?
(*blkptr)(10);
截获自动变量值
int mian(){
int val = 10;
const char *fmt = "val = %d\n";
void (^blk)(void) = ^{printf(fmt,val);};
val = 2;
fmt = "these values changed = %d\n";
blk();
//输出 val = 10
return 0;
}
Block 表达式截获所使用的自动变量的值,即保存该自动变量的瞬间值,因此在执行 Block 语法后即使改写 Block 中使用的自动变量也不会影响 Block 执行时自动变量的值
__block 说明符
使用附有 __block 说明符的变量可在Block中赋值
__block int val = 10;
void (^blk1)(void) = ^{val = 1;};
blk1();
//val = 1;
截获的自动变量
id array = [[NSMutableArray alloc] init];
void (^blk)(void) = ^{
id obj = [[NSObject alloc] init];
[array addObject:obj]; //OK
array = [[NSMutableArray alloc] init]; //报错
};
赋值给截获的值会产生编译错误,但使用截获的值却不会有问题
在使用 C 语言数组时必须小心使用指针,截取自动变量的方法没有实现对 C 语言数组的截获,需使用指针(用 char *text 而不是 char text[])
网友评论