之前讲过Block的语法,除了没有名称以及带有"^“符号意外,其他的都跟c语言函数定义相同,在定义c语言的函数时,就可以将所定义函数的地址赋值给函数指针类型变量中。
int func (int count)
{
return count + 1;
}
int (*funcptr)(int) = &func;
这样一来,函数func的地址就能赋值给函数指针类型变量funcptr中了。
同样的,在Block语法下,可将Block语法赋值给声明为Block类型的变量中。即源代码中一旦使用Block语法就相当于生成了可赋值给Block类型变量的“值”。Blocks中由Block语法生成的值也被称为“Block”。在有关Blocks的文档中,“Block”即指源代码中的Block语法,也指由Block语法所生成的值。(感觉自己说了一堆废话)
声明Block类型变量的示例如下:
int (^blk)(int);
与前面的是使用函数指针的源代码对比可知,声明Block类型变量仅仅是将声明函数指针类型变量的“*”变为“^”。该Block类型变量与一般的C语言变量完全相同,可作为以下用途使用。
- 自动变量
- 函数参数
- 静态变量
- 静态全局变量
- 全局变量
那么,下面我们就试着使用Block语法将Block赋值给Block类型变量。
int (^blk)(int) = ^(int count){return count + 1;};
由“^”开始的Block语法生成的Block被赋值给赋值给变量blk中。因为与通常的变量相同,所以当然也可以由Block类型向Block类型变量赋值。
int (^blk1)(int) = blk;
int (^blk2)(int);
blk2 = blk1;
在函数参数中使用Block类型变量可以向函数传递Block。
void func (int (^blk)(int))
{
}
在函数返回值中指定Block类型,可以将Block作为函数的返回值返回。
int (^func())(int)
{
return ^(int count){return count + 1;};
}
由此可知,在函数参数和返回值中使用Block类型变量时,记述方式极为复杂。这是,我们可以像使用函数指针类型时那样,使用typedef来解决该问题。
typedef int (^blk_t)(int);
如上所示,通过使用typedef可声明“blk_t”类型变量。我们试着在以上例子中的函数参数和函数返回值部分里使用一下。
/*原来的记述方式
void func(int (^blk)(int))
*/
void func(blk_t blk)
{
/*原来的记述方式
int (^func()(int))
*/
blk_t func()
}
通过使用typedef,函数定义就变得更加容易理解了。
另外,将赋值给Block类型变量中的Block方法像C语言通常的函数调用那样使用,这种方式与使用函数指针类型变量调用函数的方式几乎完全相同。变量funcptr为函数指针类型时,像下面这样调用函数指针类型变量:
int result = (*funcptr)(10);
变量blk为Block类型的情况下,这样调用Block类型变量:
int result = blk(10);
通过Block类型变量调用Block与C语言通常的函数调用没有区别。在函数参数中使用Block类型变量并在函数中执行Block的例子如下:
int func(blk_t blk,int rate)
{
return blk(rate);
}
当然,在OC的方法中也可使用。
- (int) methodUsingBlock:(blk_t)blk rate:(int)rate
{
return blk(rate);
}
Block类型变量可完全像通常的C语言变量一样使用,因此也可以使用指向Block类型变量的指针,即Block的指针类型的变量。
typedef int (^blk_t)(int);
blk_t blk = ^(int count){return count + 1;};
blk_t * blkptr = &blk;
(*blkptr)(10);
由此可知Block类型变量可像C语言中的其他类型变量一样使用。