iOS Block学习笔记(一) -- Block变量与C语言函
2018-11-02 本文已影响22人
brownfeng
C语言中的函数与函数指针
一般我们称Block是匿名函数, 匿名函数就是没有名称的函数, 本文就来梳理Block和C语言函数的联系.
在C语言中, 函数的声明, 定义和调用如下:
// 定义函数
int func(int arg) {
printf("%d\n", arg);
return arg;
};
// 调用函数
int ret = func(10);
因此,我们看到,调用func
函数,必须使用该函数的函数名 --func
.
同时, 我们也可以声明定义一个函数指针变量, 然后用函数指针变量调用函数, 例如:
// 定义一个函数指针变量
int (*funcPtr)(int) = &func;
// 通过函数指针变量调用函数
int ret = (*funcPtr)(10);
实际,就算使用函数指针去调用函数,也是需要知道原函数的函数名,否则无法获取原函数的地址.
OC中的Block匿名函数以及Block变量
现在,OC中我们Block匿名函数的结构如下:
^ 返回值类型 参数列表 函数表达式
同上面的函数类似, Block的声明和定义以及调用如下:
// Block匿名函数的定义
^(int arg){
return arg;
};
// Block匿名函数的调用
int ret = ^(int arg){return arg;}(10);
// 定义一个Block匿名函数变量
int (^temBlock)(int arg) = ^(int arg){return arg;};
// 通过Block匿名函数变量调用匿名函数
int ret = temBlock(10);
注意我们一般说的Block, 有时候指Block匿名函数, 有时候指Block匿名函数变量, 要进行区分.后面直接说Block,和Block变量
为了让我们看的更加清楚, 我们将函数指针变量和block变量卸载一起:
int func(int arg) {
return arg;
};
int (*funcPtr)(int) = &func;
int ret = funcPtr(10);
int (^tmpBlock)(int arg) = ^(int arg){
return arg;
};
int ret = tmpBlock(10);
因此,我们可以看到函数指针类型变量
-- int (*funcPtr)(int)
和 Block类型变量
-- int (^tmpBlock)(int arg)
两个非常相似, Block类型变量
仅仅是将声明函数指针类型变量
的*
变为^
.
其他语言中的匿名函数, 我们看到闭包(Closure), lambda等也是匿名函数的别称
Block变量的用途
Block变量可以用于如下用途:
1. 自动变量
2. 函数参数
3. 静态变量
4. 静态全局变量
5. 全局变量
例如:
//1. 自动变量
int (^blk)(int) = ^(int arg) {return arg;};
int (^blk1)(int) = blk;
int (blk2)(int);
blk2 = blk1;
//2. 函数参数
void func(int arg,int (^blk)(int)){
blk(arg);
}
//3. 函数返回值
int (^func())(int){
return ^(int arg){return arg;};
}
上面形式看不清楚可以用 typedef来解决该问题:
typedef int (^blk_t)(int);
void func(int arg,int (^blk)(int)){
blk(arg);
}
void func(int arg, blk_t blk){
blk(arg);
}
int (^func())(int){
return ^(int arg){return arg;};
}
blk_t func(){
return ^(int arg){return arg;};
}
因此Block变量可以像C语言中的其他变量一样使用.
参考资料
- <<Objective-C 高级编程: iOS与OSX多线程和内存管理>>