函数式编程
编程思想
:把过程尽量写成一系列嵌套的函数。(函数式编程更加强调程序执行的结果而非执行的过程,函数式编程中的函数指的并不是编程语言中的函数(或方法),它指的是数学意义上的函数,即映射关系)
函数式编程特点
:
1.可以把函数作为参数进行传递(在OC中就是将block作为方法参数传递)
2.可以将函数作为返回值(在OC中就是将block作为方法返回值)
使用函数式编程的例子就太多了,比如AFN
,以及我们平常写ViewModel的请求回调等。
1.block作为参数
方法声明
//方法声明
- (void)play:(void(^)(void))block;
方法实现
//方法实现
- (void)play:(void(^)(void))block
{
block();
}
方法调用
//方法调用
Person * p = [[Person alloc] init];
[p play:^{
NSLog(@"玩个球...");
}];
2.block作为返回值
方法声明
//无参 无返回值
- (void(^)(void))play;
//有参 无返回值
- (void(^)(NSString *))eat;
//有参 有返回值
- (NSString *(^)(NSString *))sleep;
方法实现
//无参 无返回值
- (void(^)(void))play
{
return ^(){
NSLog(@"来和妲己玩耍吧~");
};
}
//有参 无返回值
- (void(^)(NSString *))eat
{
return ^(NSString * food){
NSLog(@"吃了:%@~",food?:@"");
};
}
//有参 有返回值
- (NSString *(^)(NSString *))sleep
{
return ^(NSString * dream){
return [NSString stringWithFormat:@"做了个梦:%@",dream?:@""];
};
}
方法调用
Person * p = [[Person alloc] init];
p.play();
p.eat(@"牛排");
NSString * desc = p.sleep(@"你是猪");
需要说明的是OC想要使用.
语法来调用方法,只有get
和set
两种方式
get
方法:有返回值,没有参数
set
方法:有参数,无返回值
而我们调用p.eat(@"牛排")
,eat 是get
方法,之所以能传参数,是因为eat的返回值是带参数的block
,block如何调用?这个要不会罚你到幼儿园复习一年!😏所以()
其实是block的调用,而@"牛排"
则是block的参数。
链式编程
编程思想
:把多个方法使用点语法链接起来,让代码更加简洁,可读性更强
编程特点
:方法的返回值必须是调用者本身
方法声明
- (Person *)eat;
- (Person *)sleep;
方法实现
- (Person *)eat
{
NSLog(@"吃东西~");
return self;
}
- (Person *)sleep
{
NSLog(@"睡觉喽~");
return self;
}
方法调用
Person * p = [[Person alloc] init];
//吃完就睡,睡醒就吃
p.eat.sleep.eat;
函数式+链式编程
函数式链式编程就是将两种编程思想结合起来,使代码更紧凑,更优雅。如果大家想深入了解函数式链式编程的魅力可以看一下Masonry
源码,以下是一个简单的例子说明。
方法声明
- (Person *(^)(NSString *))eat;
- (Person *(^)(NSString *))play;
- (Person *(^)(NSString *))sleep;
方法实现
- (Person *(^)(NSString *))eat
{
return ^(NSString * food){
NSLog(@"吃了:%@",food?:@"");
return self;
};
}
- (Person *(^)(NSString *))play
{
return ^(NSString * toy){
NSLog(@"玩了:%@",toy?:@"");
return self;
};
}
- (Person *(^)(NSString *))sleep
{
return ^(NSString * dream){
NSLog(@"梦见:%@",dream?:@"");
return self;
};
}
方法调用
Person * p = [[Person alloc] init];
p.eat(@"牛排").play(@"足球").sleep(@"你是猪");
输出
2020-12-09 11:21:33.709949+0800 Demo[35715:15437815] 吃了:牛排
2020-12-09 11:21:33.710440+0800 Demo[35715:15437815] 玩了:足球
2020-12-09 11:21:33.710467+0800 Demo[35715:15437815] 梦见:你是猪
2020-12-09 11:21:33.847314+0800 Demo[35715:15437815] Metal API Validation Enabled
应用场景
其实函数式链式编程可应用的场景还挺多的,比如:
- UIView设置指定边框
- UIView设置指定圆角
先简单记录一下,方便后续一一实现~
结语
条条大路通罗马,关键在于选择最短的一条。高级不一定适用,合适才是最好的。GoodBye~😉