【block作为函数的参数 Objective-C语言】

一、block作为函数的参数

1.block是1个数据类型,能不能作为函数的参数呢,可以

2.例如,我有1个test函数,现在我要给它定义1个参数,定义1个block类型的参数,什么样的block呢,无参数、无返回值的block

main.m文件中

import <Foundation/Foundation.h>

//为这个函数定义1个参数,定义1个block类型的参数

//无参数、无返回值的block

//如果要给它定义1个int类型的参数,就在小括号里面声明1个int类型的变量就可以了,例如void test(int num)

//如果要定义1个float类型的参数,就在小括号里面声明1个float类型的变量就可以了,例如void test(float f1)

//如果要定义1个block类型的参数,就在小括号里面声明1个block类型的变量就可以了,例如void test(void (^block1)())

void test(void (^block1)())

{

NSLog(@“--------------------”);

}

int main()

{

return 0;

}

这个时候,我是不是就在test()这个函数的小括号里面,声明了1个无参数、无返回值的block变量了啊,那么这个时候,这个block1就是这个test()函数的参数

这个参数block1是不是存储了代码啊,那么我就执行1下这个参数里的代码,如下:

void test(void (^block1)())

{

NSLog(@“--------------------”);

block1();

NSLog(@“--------------------”);

}

int main()

{

return 0;

}

3.如何为函数定义1个block类型的参数

1)在函数的小括弧里面,声明1个指定格式的block类型的变量就可以了

2)如果看见上面这个写法有点晕:

void test(void (^block1)()){

NSLog(@“----------------”);

block1();

NSLog(@“----------------”);

}

那就通过typedef把它弄成短格式就可以了

import <Foundation/Foundation.h>

typedef void (^NewType)();

void test(NewType block1){

NSLog(@“----------------”);

block1();

NSLog(@“----------------”);

}

声明1个NewType类型的block1

那么这个block1是什么类型的呢

无返回值、无参数的block类型

3)可以使用typedef简化block的定义,这样看起来就不会恶心了,想吐了

4.如何去调用带block参数的函数呢

1)这样写是不行的:

#import <Foundation/Foundation.h>

typedef void (^NewType)();

void test(NewType block1){

NSLog(@“--------------”);

block1();

NSLog(@“---------------”);

}

int main(){

test();

return 0;

}

这样写是不行的,因为这个test()函数,是不是有个参数啊,有参数就要传参啊

但是这个时候,我们这个函数的参数是个block

那我该怎么传呢

2)如果要调用的函数的参数是1个block 类型的,那么要求在调用的时候传入1个和形参block要求的代码段

第一步,在main.m文件中,先声明1个block类型的变量

int main(){

NewType type = ^void(){

NSLog(@“哈哈。。。”);

NSLog(@“呵呵。。。”);

NSLog(@“嘿嘿。。。”);

};

test(type);

return 0

}

输出:

----------------------

哈哈。。。

呵呵。。。

嘿嘿。。。

------------------------

3)上面这段代码怎么执行的,先执行main函数吧,从上往下执行,执行到第一句话:

NewType type = ^void(){

NSLog(@“哈哈。。。”);

NSLog(@“嘿嘿。。。”);

NSLog(@“呵呵。。。”);

};

在内存中开辟1块空间,命名为type ,这是1个block类型的变量,把下面的代码赋值给它:

NSLog(@“哈哈。。。”);

NSLog(@“嘿嘿。。。”);

NSLog(@“呵呵。。。”);

然后再执行这句话:

test(type);

执行test函数怎么执行的,第一步,加载函数,加载到代码段里,第二步,声明函数的参数,形参,在内存中开辟1块儿空间,就是这个block1,形参,第三步,传参,把实参传给形参,传参的本质是赋值,把实参的值赋值给形参,而现在实参是type,实参type的值是什么,是不是这段代码啊:

NSLog(@“哈哈。。。”);

NSLog(@“嘿嘿。。。”);

NSLog(@“呵呵。。。”);

好,把实参type的值,咔,赋给block1,这就是传参

第四步,执行函数体

打印1句:NSLog(@“----------------”);

执行参数block1里面的代码:block1();

而这个时候,参数block1里面的代码是什么啊,是不是下面这段代码啊:

NSLog(@“哈哈。。。”);

NSLog(@“嘿嘿。。。”);

NSLog(@“呵呵。。。”);

然后再打印这个波浪线:NSLog(@“-----------------”);

所以这就是,如何去调用带block参数的函数

4.假设有1个test1函数:

void test1(int num)

{

//函数体

}

现在我要调用test1函数:

int main() {

int age = 10;

test1(age);

}

这种调法跟上面的是一样的,先把数据放到1个变量里面去,然后再把变量传过去

另一种方法,直接写个10也是可以的吧?

int main(){

test1(10);

}

所以,第二种调用带block参数函数的方式,直接把值传过去

int main(){

test(^void(){

NSLog(@“哈哈。。。”);

NSLog(@“呵呵。。。”);

NSLog(@“嘿嘿。。。”);

);

}

5.调用的时候,可以先将代码段存储到1个block变量,然后再传递这个block变量

也可以直接将符合要求的代码段写在小括弧中传递

6.调用带block参数的函数的第三种方式:

要调用test()函数:

test(^(void)block1);

上面是写完test直接按Tab键自动补全的:

这时候,光标停在^(void)block1这里,直接按回车

这时候,出现的是下面的代码,直接把block框架给你写好了,你只需写代码就可以了:

test(^{

code//这一行是选中的状态

});

7.再来一个复杂一点的block,带参数的:

void test2(int (^paramsBlock)(int num1,int num2))

{

//函数体

}

返回值是int,两个整形的参数的block,作为test2函数的参数

实现一下这个函数:

void test2(int (^paramsBlock)(int num1,int num2))

{

NSLog(@“------------------------------”);

int sum = paramsBlock(10,20);

NSLog(@“sum = %d”,sum);

NSLog(@“------------------------------”);

}

现在,我要去调用这个test2函数:

int main()

{

test2();//回车、回车、。。。、没反应

//这是由于编译器还没有反应过来,command+B强制编译一下,再按回车,就有提示了,再按回车,就自动帮你把block的框架写好了,你只需写代码就可以了

test2(^int(int num1,int num2){

return num1+num2;

});

在main.m函数中调用一下带1个有两个参数,返回值类型是int的block参数的函数test2试一下

int main(){

test2(^int(int num1,int num2){

return num1+num2;

});

return 0;

}

输出:

------------------------------

sum = 30;

-----------------------------

二、小技巧:

1.通过Xcode的提示,可以快速生成block代码段的框架

三、最后,大家思考一下,把block作为函数的参数,它能够实现什么样的效果

1.换句话说,我们什么时候需要把block作为函数的参数

大家思考一下,这段代码是谁写的:

NSLog(@“哈哈。。。”);

NSLog(@“呵呵。。。”);

NSLog(@“嘿嘿。。。”);

调用者写的

把block作为函数的参数,就可以把调用者写的一段代码,放到函数的内部去执行

2.所以,把block作为函数的参数的作用为:

可以将调用者自己写的1段代码,传递到函数的内部去执行

3.例如:

void test(void (^block1)(){

NSLog(@“----------------------------”);

block1();

NSLog(@“---------------------------”);

});

在main.m文件中:

int main(){

test(^void(){

NSLog(@“我爱广州小蛮腰。”);

NSLog(@“北京天安门。”);

});

//你看这个时候,这段代码是谁写的:

NSLog(@“我爱广州小蛮腰。”);

NSLog(@“北京天安门。”);

调用者写的

这个时候,我可以把调用者写的代码,传到另外一个函数的内部去执行

你想一下啊,能不能用别的方式实现这种效果:

函数指针,还有别的方法吗,没了吧

以前的参数都是int啊,float啊,例如:

void test(int num)

这个方式,可以把调用者的应用数据传给这个函数,让这个函数去用

而block呢,可以把调用者的代码,传递到函数的内部去执行

猜你喜欢

转载自blog.csdn.net/madoca/article/details/126824067
今日推荐