我们经常使用的开源框架 Masonry 就是使用这样的编程思想,Masonry是一个OC开发中,非常好用的自动布局框架,通过点语法来进行多个操作
代码示例:
[greenView makeConstraints:^(MASConstraintMaker *make) {
make.top.greaterThanOrEqualTo(superview.top).offset(padding);
make.left.equalTo(superview.left).offset(padding);
make.bottom.equalTo(blueView.top).offset(-padding);
make.right.equalTo(redView.left).offset(-padding);
}];
这种将多个操作(多行代码)通过点号(.)链接在一起成为一句代码,使代码可读性提高,我们称之为链式编程。
链式编程特点:方法的返回值是block,block必须返回对象本身(返回block时,block所在的方法调用者对象)block的参数是需要操作的值。
下面通过一个简单的示例解读链式编程,展示链式编程的魅力。
1. 创建Person类
person.h 头文件
#import
@interface Person : NSObject
- (Person* (^)())eat;
- (Person* (^)())go;
- (Person* (^)(NSString *))study;
@end
person.m 实现文件
#import "Person.h"
@implementation Person
//该函数返回一个 Person* (^)() 类型的 block 变量,当该类对象调用 block() 会打印eat 并且返回该当前类对象
- (Person* (^)())eat
{
//block变量保存的代码段
Person* (^block)() = ^(){
NSLog(@"eat");
//返回当前类对象
return self;
};
//返回block变量
return block;
}
- (Person* (^)())go
{
return ^Person *(){
NSLog(@"go go go");
return self;
};
}
//该函数返回一个 Person* (^)(NSString *) 类型的 block 变量
- (Person* (^)(NSString *))study
{
Person* (^block)(NSString *) = ^(NSString *yyy){
NSLog(@"%@ study",yyy);
return self;
};
return block;
}
@end
2. 调用示例:
Person *person = [Person new];
person.eat().go().study(@"good good");
3. 输出结果:
2016-02-26 14:37:06.179 Day2016-02-26-函数编程[2579:87725] eat 2016-02-26 14:37:06.180 Day2016-02-26-函数编程[2579:87725] go go go 2016-02-26 14:37:06.180 Day2016-02-26-函数编程[2579:87725] good good study
4. 分析:
分解以上调用的代码
第一步:执行 person.eat 返回对应的eatBlock变量。
Person* (^eatBlock)() = person.eat;
第二步:执行eatBlock,此时返回当前person对象。
person = eatBlock();
第三步:执行 person.go 返回对应的goBlock变量。
Person* (^goBlock)() = person.go;
第四步:执行goBlock,此时返回当前person对象。
person = goBlock();
第五步:执行 person.study 返回对应的studyBlock变量。
Person* (^studyBlock)(NSString *) = person.study;
第六步:执行studyBlock,此时返回当前person对象。
person = studyBlock(@"good good");
按照分解步骤调用实现:
Person *person = [Person new];
Person* (^eatBlock)() = person.eat;
person = eatBlock();
Person* (^goBlock)() = person.go;
person = goBlock();
Person* (^studyBlock)(NSString *) = person.study;
person = studyBlock(@"good good");
输出结果:
2016-02-26 15:40:34.371 Day2016-02-26-函数编程[2948:107876] eat 2016-02-26 15:40:34.371 Day2016-02-26-函数编程[2948:107876] go go go 2016-02-26 15:40:34.372 Day2016-02-26-函数编程[2948:107876] good good study
这样就可以一直链接下去吧!实现了我们想要的目标!
5. 函数式编程总结
如果想再去调用别的方法,那么就需要返回一个对象;
如果想用()去执行,那么需要返回一个block;
如果想让返回的block再调用对象的方法,那么这个block就需要返回一个对象(即返回值为一个对象的block)