我们如果在完成一件事情的时候,可能会需要有很多步骤,那我们其实就可以把这个步骤看成是一个一个的过程,然后再去组合起来,这样会比较的清晰。就比如说学生要吃饭,读书,跑步我们如果直接去调用方法的话是直接如以下步骤所示去调用的,这就是去实现吃饭,学习,跑步。这里需要注意的是无参数的方法也是可以通过点的形式也就是 . 去调用的。
-(void)study
{
NSLog(@"学习");
}
-(void)eat
{
NSLog(@"吃饭");
}
-(void)run
{
NSLog(@"跑步");
}
去调用下面的方法
[student eat];
[student study];
[student run];
当然我们还可以这么做也相当于是实现了链式存储,但是这样一直下去会不好去阅读
-(Student *)study
{
NSLog(@"学习");
return self;
}
-(Student *)eat
{
NSLog(@"吃饭");
return self;
}
-(void)run
{
NSLog(@"跑步");
}
然后去调用
[[[student eat]study]run];
这个时候我们应该去用block来实现,虽然说免不了调用的方法次数较多,使得整行代码较长,通过换行还能保持一定的阅读性,还是会显的很清晰。
-(Student *(^)())study
{
return ^{
NSLog(@"study");
return self;
};
}
-(Student *(^)())run
{
return ^{
NSLog(@"跑步");
return self;
};
}
-(Student *(^)())eat
{
return ^{
NSLog(@"吃饭");
return self;
};
}
我们调用就可以直接通过点语法的方式去调用了,这里的. 其实就相当于是获取这个block,然后()就相当于是去调用
student.eat().study().run();
如果我们要携带参数的话需要在block中携带参数,如果直接在函数外面写参数就无法再通过点语法就行调用了,所以我们应该这么写
-(Student *(^)(NSString * string))study
{
return ^(NSString * string){
NSLog(@"study");
NSLog(@"%@",string);
return self;
};
}
其实Masonry中就很好的用到了链式编程的思想。也就是说方法的返回值是block,block还有返回值
函数式编程
函数式的话其实就是你调用的代码和你处理的业务逻辑在一起的话就是函数式,比如说你有一个方法是有一个block作为参数的,我们在block里面写我们要处理的逻辑代码就是函数式编程。函数式编程的可读性好的原因就是往方法中传入了Block,方法中嵌套Block调用的话,其实就是把代码聚合起来管理。
函数式编程的特点是每个方法必须有返回值(本身对象),把函数或者block当做参数。block可以作为参数也可以作为返回值。在函数式编程中,函数就是一个管道,通过这个管道,进去一个值和出来一个值会存在一定的映射关系,就好比我们数学上的我们学的函数是一样的,都是满足了一定的规律才可以构成一个函数
函数式编程有两个最基本的运算:合成和柯里化
如果一个值要经过多个函数,才能变成另外一个值,就可以把所有中间步骤合并成一个函数,这叫做函数的合成
f(x)和g(x)可以简单的合成为f(g(x)),但是有一个前提,就是f和g都只能接受一个参数。如果可以接受多个参数,比如f(x, y)和g(a, b, c),函数合成就非常麻烦。
这时就需要函数柯里化了。柯里化,就是把一个多参数的函数,转化为单参数函数。举个下面的例子比如说加法函数,转换为单一参数的函数的例子
//原先的加法函数
func add(x:Int,y:Int)->Int
{
return x+y
}
//柯里化
func add(_ x:Int) ->(Int)->Int
{
let addy:(Int)->Int = {(y) in
return x+y
}
return addy
}
print(add(1)(2)) //3
响应式编程
如果是响应式编程的话其实就是和方法的实现有关的,也就是说我们去定义方法的时候只根据某些特定的条件去判断调用那些代码,就比如说AFN中的如果成功的返回数据调用一个block,如果是失败又调用另外一个block。也就是说在方法的内部实现不知道你代码是如何实现的,只是知道返回什么数据,给你响应你写的代码的执行。
KVO和通知和代理其实都是响应式编程的体现。
补充:
只要我们定义的方法没有参数就是一个get方法就可以使用点语法。如果方法的返回值是block的,而且也不带参数也可以用点语法,包括我们的类方法也是如此,类方法没有参数的也可以用点语法完成,只是如果没有返回值,会有下面的警告而已