链式编程是讲多个操作通过点操作串联起来,方便函数的调用和可读性,比如说大家常举的计算器例子:
NSInteger result = adder.add(4).sub(1).mult(2).div(3);表示(4+1)*2/3,是不是很方便很直观。
我们知道,如果是c++的实现话链式操作是很简单的,因为c++的函数调用就是通过点操作调用的,只需要返回对象本身就可以实现链接了。但是oc就不行了,因为oc的点操作表示的get或是set,点操作只能用作属性变量。但在oc中好像我们也见过这样的调用:obc.action();看着不是很直观,但这样obc.actionBlock();可能就有点眼熟了,对就是block的调用!但问题又来了,block是可以实现点操作,那怎么像这样obc.actionBlock().actionBlock()链接起来串行调用呢?再想想c++的返回对象本身,对block中返回函数本身应该就可以了。试一下:
1、声明返回值为自身对象、传入参数为整形的block :
typedef Caculator *(^IBlock) (NSInteger iNum);
2、声明计算器对象:
//Caculator.h
@interface Caculator : NSObject
@property (nonatomic, readonly) NSInteger result;
- (IBlock) add;
@end
@implementation Caculator
//Caculator.m
- (IBlock) add {
IBlock block = ^ (NSInteger num) {
_result += num;
return self;
};
return block;
}
@end
3、使用方法:
Calculator *caculator = [[Caculator alloc] init];
caculator.add(10).add(10);
NSLog(@"result = %ld", (long)caculator.result);
是不是实现了链式调用啊!///////////////////////////////////////////////////////////////////////////////////////
进一步的优化调用:
由于add返回的是对象本身,显然不能这么使用:NSInteger result = caculator.add(10).add(10);这样使用会方便些,但如果能这样的话无疑会更加方便。
怎么办呢?这能在封装一层,转化一下。
//Caculator.h
+ (NSInteger)caculator:(void (^)(Caculator *make)) caculator;
//Caculator.m
+ (NSInteger)caculator:(void (^)(Caculator *make)) caculator {
Caculator *tCaculator = [Caculator new];
caculator(tCaculator);
return tCaculator.result;
}
使用方法:
NSInteger result = [Caculator caculator:^(Caculator *make) {
make.add(2).add(10).div(2);
}];