「函数式编程」:每个函数都有返回,函数作为第一类对象
「链式编程」:函数返回的对象继续进行函数,组成一串长链(函数式编程的体现?)
- 拿 jQuery 简单举个例子
var text = $('#content').children().eq(1).children().eq(0).text();
- 对比 Object-C,
// 执行方法,而不是函数,没有返回,虽然参数部分有返回,但是毕竟是面向对象
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:NSStringFromClass([UITableViewCell class])];
// 就算使用返回 self,写链式也很难受
[[[person eat] run] eat];
OC 实现「函数编程」与「链式编程」
-
.
语法使用,是对象属性 - 使属性拥有参数,需要 block 函数闭包作为属性
// 定义 block
typedef Person* (^eatBlock)(NSString *name);
// block 作为属性
@property (nonatomic, copy) eatBlock eat;
// block 的 getter 方法,本身是函数,可以引入参数,而函数又返回 self,得以继续
- (eatBlock)eat {
return ^Person* (NSString *a) {
NSLog(@"吃了:%@",a);
return self;
};
}
Person *person = [[Person alloc] init];
person.eat(@"苹果").eat(@"橘子").eat(@"香蕉");
抛开实例,只关注函数结果
- 可以把实例本身封装起来
NSString *resMessage = [Person makeMessage:^(Person *person) {
person.eat(@"橘子").run(12).pause.eat(@"苹果");
}];
- 部分代码
@implementation Person
- (NSMutableArray *)infoList {
if (!_infoList) {
_infoList = [NSMutableArray array];
}
return _infoList;
}
+ (NSString *)makeMessage:(void(^)(Person *person))block {
if (block) {
Person *person = [[Person alloc] init];
block(person);
return [person.infoList componentsJoinedByString:@","];
}
return nil;
}
- (eatBlock)eat {
return ^Person* (NSString *a) {
NSLog(@"吃了:%@",a);
[self.infoList addObject:[NSString stringWithFormat:@"吃了 %@", a]];
return self;
};
}
- (runBlock)run {
return ^Person *(NSInteger step) {
NSLog(@"走了:%zi 步", step);
[self.infoList addObject:[NSString stringWithFormat:@"走了 %zi 步", step]];
return self;
};
}
- (Person *)pause {
NSLog(@"休息一下");
[self.infoList addObject:@"休息以下"];
return self;
}
@end
block 回顾
内部 block
// 定义方法
- (NSInteger)sumWithA:(NSInteger)a b:(NSInteger)b {
return a + b;
}
// 定义 block
NSInteger (^sum)(NSInteger, NSInteger) = ^(NSInteger a, NSInteger b) {
return a + b;
};
NSInteger res1 = [self sumWithA:1 b:2];
NSInteger res2 = sum(1, 2);
实例 block
@property (nonatomic, copy) NSInteger(^block)(NSInteger a, NSInteger b);
self.block = ^(NSInteger a, NSInteger b) {
return a + b;
};
NSInteger res = self.block(1, 2);
block 的 getter 与 setter
typedef NSInteger(^typeOfBlock)(NSInteger a, NSInteger b);
@property (nonatomic, copy) typeOfBlock typeBlock;
getter
- 实际获取了 block 函数本身,可以当成函数使用(向里传参)
- (typeOfBlock)typeBlock {
return ^NSInteger(NSInteger a, NSInteger b) {
return a + b;// 此处是 block 函数执行体
};
}
NSInteger res4 = self.typeBlock(2, 3);
setter(正常实例)
- 给实例指定 block 函数(与实例一样的 get 和 set)
- 这个应该不怎么用吧,仅仅把函数执行体,放到外面而已
- (void)setTypeBlock:(typeOfBlock)typeBlock {
if (!_typeBlock) {
_typeBlock = typeBlock;
}
}
[self setTypeBlock:^NSInteger(NSInteger a, NSInteger b) {
return a + b;// 此处是 block 函数执行体
}];
setter 2(内部调用)
- 内部使用了 block,即可反向传参,因为执行体在外面(向外传参)
- 这个很多时候用来代替了 delegate 传参的方式
- (void)setTypeBlock:(typeOfBlock)typeBlock {
if (typeBlock) {
NSInteger res = typeBlock(2, 3);// 实际就是执行了 block 函数一次,但作用可以反向传参
NSLog(@"这里是 res:%zi", res);
}
}
[self setTypeBlock:^NSInteger(NSInteger a, NSInteger b) {
NSLog(@"%zi,%zi", a, b);
return a + b;// 此处是 block 函数执行体
}];