【block作为函数的参数 Objective-C语言】
移动开发
2022-10-03 21:41:53
阅读次数: 0
一、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