OC链式编程的一个实践
2020-05-13 本文已影响0人
大刘
所谓链式编程,基本都是调用一个方法的时候返回对象本身,然后可以继续调用方法。以OC为例:
@interface Person : NSObject
- (Person *)eat:(NSString *)food;
- (Person *)drink:(NSString *)water;
- (Person *)sleep:(NSInteger)hour;
@property (nonatomic, weak, readonly) Person *(^makeFriend)(NSString *name);
@property (nonatomic, weak, readonly) Person *(^learn)(NSString *name);
@end
#import "Person.h"
@implementation Person
- (Person *)eat:(NSString *)food {
NSLog(@"eat %@", food);
return self;
}
- (Person *)drink:(NSString *)water {
NSLog(@"drink: %@", water);
return self;
}
- (Person *)sleep:(NSInteger)hour {
NSLog(@"sleep: %ld hours", (long)hour);
return self;
}
- (Person * _Nullable (^)(NSString * _Nonnull))makeFriend {
return ^Person *(NSString *name) {
NSLog(@"make friend: %@", name);
return self;
};
}
- (Person * _Nullable (^)(NSString * _Nonnull))learn {
return ^Person *(NSString *name) {
NSLog(@"learn: %@", name);
return self;
};
}
@end
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p = Person.new;
[[[p eat:@"兰州拉面"] drink:@"水"] sleep:3].learn(@"数学").makeFriend(@"路飞");
}
return 0;
}
不过OC使用中括号调用方式的链式编程写起来不如点语法舒服。从底层支持链式编程的语言当数用于Fluuter的Dart语言,直接obj..method1()..method2()..
,这是从语言底层直接支持。 写这种代码,Swift要比OC有优势。
我们知道这种写法能做些什么呢?Masonry就是使用这种思想来做的。在实际的工作中,我的一个工作经历是,项目中使用的是全是OC,在对视图进行赋属性时往往是:
UIView *view = UIView.new;
view.backgroudColor = ...
view.frame = ..
...
当时我想是否可以用链式思想简化一些写法,哪怕只是语法糖,但仍然是一件有意思的事情,于是花了半天时间写了出来,但是由于OC对泛型的支持并不彻底,在用OC写时做了一点手脚,最后调用代码如下:
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:UIButton.new
.dl_frame(CGRectMake(0, 0, 100, 100))
.dl_backgroundColor(UIColor.redColor)
.dl_titleColorForState(UIColor.whiteColor, UIControlStateNormal)
.dl_titleForState(@"Click me", UIControlStateNormal)
.dl_center(self.view.center)
.dl_cornerRadius(8)
.dl_clipsToBounds(YES)
.dl_addTargetAction(self, @selector(buttonClick:), UIControlEventTouchUpInside)];
}
我这里用自己的名字“大刘 dl_”作为前缀和系统方法区分。这里 是源码代实现。