Blocks(一)

作者: yzawyx0220 | 来源:发表于2016-12-19 16:37 被阅读36次

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语言类型一样。
未完待续。

相关文章

网友评论

    本文标题:Blocks(一)

    本文链接:https://www.haomeiwen.com/subject/lnstvttx.html