软件随想录提到了函数式编程的种种好处。
ios 在去年函数式编程就非常火了。swift当然支持了。
但目前基本没有编写swift,所以讨论一下oc怎么写函数式编程。
思路就是写将软件随想录的举例代码转成oc的方式。
首先是一个简单的炒菜的例子
- (void)function2
{
NSLog(@"get the lobster");
[self putInPot:@"lobster"];
[self putInPot:@"water"];
NSLog(@"get the chicken");
[self boomBoom:@"chicken"];
[self boomBoom:@"coconut"];
}
- (void)putInPot:(NSString *)material
{
NSLog(@"put %@ in pot!",material);
}
- (void)boomBoom:(NSString *)material
{
NSLog(@"BoomBoom %@!",material);
}
我们可以从中抽出一部分代码改为
- (void)function3
{
[self cook:@"lobster" andmaterial2:@"water" andSEL:@selector(putInPot:)];
[self cook:@"chicken" andmaterial2:@"coconut" andSEL:@selector(boomBoom:)];
}
- (void)cook:(NSString *)material1 andmaterial2:(NSString *)material2
andSEL:(SEL)selSecltor
{
NSLog(@"get the %@",material1);
[self performSelector:selSecltor withObject:material1];
[self performSelector:selSecltor withObject:material2];
}
oc 是能够传递方法的,但是有存在内存泄露的可能性。
但是与表达式结构,存在明显的差异性。就是表达式结构可在传递的方法改成自己想要的任意的方法,这个方法可以随便写,想改成什么样子都行,而不需要提前实现一个新的方法。
oc 中 可以使用block 来实现。我尝试改写block
typedef void (^putInPotBlock )(NSString *material);
typedef void (^boomBoomBlock )(NSString *material);
- (void)funciton4
{
putInPotBlock putInPotblock = ^(NSString * material) {
NSLog(@"put %@ in pot!",material);
};
[self cook:@"lobster" andmaterial2:@"water" andBlock:putInPotblock];
boomBoomBlock boomBoomblock = ^(NSString * material) {
NSLog(@"BoomBoom %@!",material);
};
[self cook:@"chicken" andmaterial2:@"coconut" andBlock:boomBoomblock];
}
- (void)cook:(NSString * )material1 andmaterial2:(NSString *)material2
andBlock:(putInPotBlock)block
{
NSLog(@"get the %@",material1);
if (block) {
block(material1);
block(material2);
return;
}
}
看上去没啥问题,想传递什么block 就可以传递什么block,但是有个很明显的错误,block 回传问题,block 不能判断类型。。。因此不能够判断出是 putInPotBlock 还是 boomBoomBlock 所以就很尴尬了
这个方法行不通,但是可以用类来绕过去。
@interface blockClass: NSObject
typedef void (^putInPotBlock )(NSString *material);
typedef void (^boomBoomBlock )(NSString *material);
@property(nonatomic, strong) putInPotBlock putinPotBlock;
@property(nonatomic, strong) boomBoomBlock boomboomBlock;
@end
@implementation blockClass
@end
- (void)funciton5
{
blockClass *blocktestClass = [[blockClass alloc] init];
blocktestClass.putinPotBlock = ^(NSString * material) {
NSLog(@"put %@ in pot!",material);
};
[self cook:@"lobster" andmaterial2:@"water" andMyBlock:blocktestClass];
blockClass *blocktestClass2 = [[blockClass alloc] init];
blocktestClass2.boomboomBlock = ^(NSString * material) {
NSLog(@"BoomBoom %@!",material);
};
[self cook:@"chicken" andmaterial2:@"coconut" andMyBlock:blocktestClass2];
}
- (void)cook:(NSString * )material1 andmaterial2:(NSString *)material2
andMyBlock:(id)myBlock
{
NSLog(@"get the %@",material1);
if ([myBlock isKindOfClass:[blockClass class]]) {
blockClass *block = (blockClass *)myBlock;
if (block.putinPotBlock) {
block.putinPotBlock(material1);
block.putinPotBlock(material2);
return;
}else if (block.boomboomBlock) {
block.boomboomBlock(material1);
block.boomboomBlock(material2);
return;
}
}
}
这样就实现了,但是实现的完全不优雅,并且还是要在方法里面写回调的。到这里我就不清楚进一步怎么进行下去了。现在网络上多的都是链式编程和响应式编程。没看到太多用oc写函数式编程的方案。如果有思路,后续再使用吧。