什么是 Block
Block 是 C 语言的扩充功能,带有自动变量(局部变量)的匿名函数。
Block 的语法
Block 和普通的 Objective-C 函数区别是没有函数名,且返回值前加一个^
标志。Block 完整的语法: ^
返回值类型
参数列表
表达式
如下形式的函数就是 Block:
^int (int count){ return count + 1; };
Block 语法可省略好几个项目。首先是返回值类型,语法变为:^
参数列表
表达式
。省略返回值类型时,如果表达式中有return
语句就使用该返回值的类型,如果表达式中没有return
语句就使用void
类型。前面的函数省略返回值类型时如下:
^(int count){ return count + 1; };
其次,如果不使用参数,参数列表也可省略,语法变为^
表达式
,这是 Block 最常见的使用方式。以下为不使用参数的 Block 语法:
^void (void){ printf("Blocks\n") };
省略返回类型和参数列表为如下形式:
^{ printf("Blocks\n") };
截获自动变量值
对于 Block 外的变量引用,Block 默认是将其复制到其内部变量中来实现访问的。也就是说 Block 的自动变量截获只针对 Block 内部使用的自动变量,不使用则不截获。如下代码:
int main(int argc, const char * argv[]) {
int val = 9;
const char *fmt = "val = %d\n";
void (^blk)(void) = ^{printf(fmt, val);}
val = 2;
fmt = "These values were changed, val = %d\n";
blk();
return 0;
}
结果输出:val = 9
该 Block 执行时,首先拷贝一份字符串指针“fmt = "val = %d\n"”和“val = 9”,并保存在自己的内部变量中,即使外部的fmt
和val
两个变量改变,block 内部的fmt
和val
也不会变化。
这就是自动变量值的截获。
Swift closures 和 Objective-C blocks
Swift 没有 block,取而代之的是 Closure(闭包)取代,Block 和 Closure 可相互转换。
Swift closures and Objective-C blocks are compatible, so you can pass Swift closures to Objective-C methods that expect blocks. Swift closures and functions have the same type, so you can even pass the name of a Swift function.
Closures have similar capture semantics as blocks but differ in one key way: Variables are mutable rather than copied. In other words, the behavior of __block in Objective-C is the default behavior for variables in Swift.