在接触到开源项目 Masonry 后,里面的布局约束的链式写法让我颇感兴趣,就像下面这样:
1 2 3 4 5 6 7 8 | UIEdgeInsets padding = UIEdgeInsetsMake(10, 10, 10, 10);
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(superview.mas_top). with .offset(padding.top);
make.left.equalTo(superview.mas_left). with .offset(padding.left);
make.bottom.equalTo(superview.mas_bottom). with .offset(-padding.bottom);
make.right.equalTo(superview.mas_right). with .offset(-padding.right);
}];
|
其他语言比如 Lua, 实现链式语法很容易。但在 Objective-C 中,如何实现链式语法呢?
注:这里讨论的链式语法特指的是点链式语法,不同于中括号链式语法,如[[[[someObj method1] method2] method3] method4:someParam]。中括号链式语法相对而言更简单些,每个方法的返回值是下一个方法的发送者即可。
查看 Masonry 源码,起初没看明白,于是搜索了下 Stackoverflow,没有发现类似的问题,便将这个问题发布在了 Stackoverflow 上。这里是地址。
总结了下,贴下代码,做个说明。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | @class ClassB;
@interface ClassA : NSObject
@property(nonatomic, readonly) ClassA *(^aaa)(BOOL enable);
@property(nonatomic, readonly) ClassA *(^bbb)(NSString* str);
@property(nonatomic, readonly) ClassB *(^ccc)(NSString* str);
@implement ClassA
- (ClassA *(^)(BOOL))aaa
{
return ^(BOOL enable) {
if (enable) {
NSLog(@ "ClassA yes" );
} else {
NSLog(@ "ClassA no" );
}
return self;
}
}
- (ClassA *(^)(NSString *))bbb
{
return ^(NSString *str)) {
NSLog(@ "%@" , str);
return self;
}
}
- (ClassB * (^)(NSString *))ccc
{
return ^(NSString *str) {
NSLog(@ "%@" , str);
ClassB* b = [[ClassB alloc] initWithString:ccc];
return b;
}
}
@interface ClassB : NSObject
@property(nonatomic, readonly) ClassB *(^ddd)(BOOL enable);
- (id)initWithString:(NSString *)str;
@implement ClassB
- (ClassB *(^)(BOOL))ddd
{
return ^(BOOL enable) {
if (enable) {
NSLog(@ "ClassB yes" );
} else {
NSLog(@ "ClassB no" );
}
return self;
}
}
id a = [ClassA new ];
a.aaa(YES).bbb(@ "HelloWorld!" ).ccc(@ "Objective-C" ).ddd(NO)
|