block是带有自动变量(局部变量)的匿名函数. 匿名函数就是没有名称的函数.
另外, “带有自动变量值的匿名函数”并不仅指block, 它还存在于其他程序设计语言, 在计算机科学中, 这个概念也被称为闭包,lambda计算等.
block语法
完整形式的block定义规则如下:
^ 返回值类型 (参数列表){表达式;}
完整形式的block语法与一般的C语言函数定义相比, 仅有亮点不同:
- 没有函数名
- 带有符号”^”
第一点不同是没有函数名, 因为其是匿名函数. 第二点不同是返回值类型前带有”^”(插入记号,caret).
block语法还有以下几种略写形式:
- 省略返回值类型, 如果表达式中有return语句就使用该返回值的类型, 如果表达式中没有return语句就使用void类型. 表达式中含有多个return语句时, 所有return语句的返回值类型必须相同.
- 如果不适用参数, 那么参数列表也可以省略.
- 返回值类型和参数类别均被省略.
block类型变量
声明block类型变量的示例如下:
int (^blk)(int);
声明block类型变量仅仅是将c语言中函数指针类型变量的”*”变为”^”. 该block变量与一般的C语言变量完全相同, 可以作为以下用途:
- 自动变量
- 函数参数
- 静态变量
- 静态全局变量
- 全局变量
使用typedef可以简化block语法, 下面的代码声明了一个blt_t类型:
typedef int (^blk_t)(int);
block类型变量可完全像通常的C语言变量一样使用, 因此也可以使用指向block类型变量的指针, 即block的指针类型变量.
blk_t blk = ^(int count){return count+1;};
blk_t *blkptr = &blk;
(*blkptr)(10); //11
截获自动变量值
block表达式截获所使用的自动变量的值, 即保存该自动变量的瞬间值. 所以在执行block语法后, 即使改写block中所使用的自动变量的值也不会影响block的执行值.
int val = 10;
void (^blk)() = ^{
NSLog(@"val=%d",val);
};
val = 2;
blk(); //val=10
__block说明符
自动变量值截获只能保存block执行瞬间的值, 保存后就不能在block中修改该值. 如果想要在block表达式中给block外的变量赋值, 则需要给该变量附加上__block说明符.
__block int val = 10;
void (^blk)() = ^{
val = 1;
NSLog(@"val=%d",val); //val=1
};