iOS面试基础知识点

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语言中的其他变量一样使用.

参考资料

  1. <<Objective-C 高级编程: iOS与OSX多线程和内存管理>>
上一篇下一篇

猜你喜欢

热点阅读