Block 语法
Block字面量
^ [return type] (argument list) {
expressions
}
可以省略return type
^ (argument list) {
expressions
}
当return type和参数都为空时
^void (void) {
printf("Blocks\n");
}
^{
printf("Blocks\n");
}
Block类型变量
Function变量
int func(int count)
{
return count + 1;
}
int (*funcptr)(int) = &func;
Block 变量
int (^blk)(int);
和其它C语言变量一样,Block变量能作为:
- Automatic variables, atuo变量
- Function arguments,函数参数
- Static variables,静态变量
- Static global variables,全局静态变量
- Global variables,全局变量
int (^blk)(int) = ^(int count) { return count + 1;};
int (^blk1)(int) = blk;
int (^blk2)(int);
blk2 = blk1;
Block类型可以作为函数为参数
void func(int (^blk)(int))
{
}
Block也可以作为函数的返回值
int (^func()(int)) {
return ^(int count){return count + 1;};
}
用typedef简化Block类型变量的使用
typedef int (^blk_t)(int);
/* original
void func(int (^blk)(int)){...}
*/
void func(blk_t blk){...}
/* original
int (^func()(int)){...}
*/
blk_t func(){...}
执行Block
// execute func
int result = (*funcptr)(10);
// execute block
int result = blk(10);
int func(blk_t blk, int rate) {
return blk(rate);
}
Block指针
typedef int (^blk_t)(int);
blk_t blk = ^(int count){return count + 1;};
blk_t *blkptr = &blk;
(*blkptr)(10);
获取 automatic变量
当 automatic 变量被Block获取时, 该变量在Block中是只读的 read-only. 你不能修改它.
但是如是获取的automatic变量是Objective-C对象呢?看下面代码:
id array = [[NSMutableArray alloc] init];
void (^blk)(void) = ^{
id obj = [[NSObject alloc] init];
[array addObject:obj];
};
在C语言层上,Block捕获的是NSMutableArray对象的结构体的指针。你可以修改该指针指向的对象的内容,但不能修改这个指针本身,否则编译器会报错(下面代码)。
id array = [[NSMutableArray alloc] init];
void (^blk)(void) = ^{
array = [[NSMutableArray alloc] init];
};
为了能够修改捕获的auto变量, 你需要用__block来修饰你的auto 变量。
__block id array = [[NSMutableArray alloc] init];
void (^blk)(void) = ^{
array = [[NSMutableArray alloc] init];
};
另外,当使用C数组时,请使用数组的指针。
const char text[] = "hello";
void (^blk)(void) = ^{
printf("%c\n", text[2]);
};
上面代码看上去,没任何问题,事实上,会产生编译错误:
error: cannot refer to declaration with an array type inside block printf("%c\n", text[2]);
^
note: declared here
const char text[] = "hello";
^
就是说不能在Block中使用数组,用数组的指针代替:
const char *text = "hello";
void (^blk)(void) = ^{
printf("%c\n", text[2]);
};
这样就没问题了。