Blocks是C语言的扩充功能,可以用一句话表示Blocks的扩充功能:带有自动变量(局部变量)的匿名函数。所谓匿名,就是不带名称的函数。这和C++中的lambda,swift中的闭包是一个意思,在大多数用法中,通俗的说就是可以给函数传递一个参数,这个参数不仅仅是一个参数,它还可以做一点事情,这就是Block。
语法:
^ 返回值类型 参数列表 表达式 ,像这样:
^ void (int event) { printf("buttonId:event = %d\n,event);}
完整的Block与C语言函数相比,只有两点不同:1,没有函数名;2,带有“^”。返回值类型同C语言中的函数返回类型,参数列表同C语言函数的参数列表,表达式相当于C语言函数中的表达式,当然,如果表达式中有return语句,其类型必须与返回类型相同。例如:
^int (int count) {return count + 1;}
在我们写Block的时候并不需要这么麻烦,因为Blocks可以省略很多项目,首先是返回类型。省略返回类型时,如果表达式中有return语句就是用该返回值类型,如果没有使用void,如果有多个return,类型必须一致。例如:
^ (int count) {return count + 1;}
该Block将按照return的类型返回int。
如果不使用参数,参数列表也可以省略:
^ void (void) {printf("Blocks\n");}
可以省略为:
^ {printf("Blocks\n");}
在定义C语言函数时,可以将所定义的函数的地址赋值给函数指针类型变量中,同样的,可将Block语法赋值给声明为Block的变量中。一旦使用Block语法就相当于生成了可以赋值给Block类型变量的“值”。声明Block类型变量的示例如下:
int (^blk) (int);
该Block类型变量与一般的C语言变量完全相同。赋值:
int (^blk) (int) = ^ (int count) {return count + 1;}
可以将Block作为参数传递给函数:
void func(int (^blk) (int)){}
也可以将Block作为函数的返回值:
int (^func() (int)) {return ^(int count) {return count + 1;};}
由此可知,在函数的参数和返回值中使用Block时,这种方式很复杂,我们可以用typedef来解决这个问题:
typedef int (^blk_t) (int);
那么上述的两个表达式就可以这样写:
/*原来的方式
void func(int (^blk) (int))
*/
void func(blk_t blk)
/*原来的方式
int (^func() (int))
*/
blk_t func()
可以将赋值给Block类型变量中的Block方法像C语言通常的函数调用那样使用,这种方法与使用函数指针类型变量调用函数的方法几乎完全相同:
/*函数
int result = (*funcptr) (10);
*/
int result = blk(10);
通过Block类型变量调用Block与通常的C语言函数没有区别:
int func(blk_t blk,int rate) {
return blk(rate);
}
在Objective-C中是这样的:
- (int) method:(blk_t)blk rate:(int)rate {
return blk(rate);
}
也可以使用指向Block类型变量的指针,即Block类型的指针:
typedef int(^blk_t) (int);
blk_t blk = ^(int count) {return count + 1;};
blk_t *blkptr = &blk;
(*blkptr)(10);
由此可知,Block同其他C语言类型一样。
未完待续。
网友评论