其他语言比如 Lua, 实现链式语法很容易。但在 Objective-C 中,如何实现链式语法呢?
注:这里讨论的链式语法特指的是点链式语法,不同于中括号链式语法,如[[[[someObj method1] method2] method3] method4:someParam]。中括号链式语法相对而言更简单些,每个方法的返回值是下一个方法的发送者即可。
查看 Masonry 源码,起初没看明白,于是搜索了下 Stackoverflow,没有发现类似的问题,便将这个问题发布在了 Stackoverflow 上。这里是地址。
总结了下,贴下代码,做个说明。
@class ClassB;
@interface ClassA : NSObject
// 1. 定义一些 block 属性
@property(nonatomic, readonly) ClassA *(^aaa)(BOOL enable);
@property(nonatomic, readonly) ClassA *(^bbb)(NSString* str);
@property(nonatomic, readonly) ClassB *(^ccc)(NSString* str);
@implement ClassA
// 2. 实现这些 block 方法,block 返回值类型很关键,影响着下一个链式
- (ClassA *(^)(BOOL))aaa
{
return^(BOOL enable) {
//code
if(enable) {
NSLog(@"ClassA yes");
}else{
NSLog(@"ClassA no");
}
returnself;
}
}
- (ClassA *(^)(NSString *))bbb
{
return^(NSString *str)) {
//code
NSLog(@"%@", str);
returnself;
}
}
// 这里返回了ClassB的一个实例,于是后面就可以继续链式 ClassB 的 block 方法
// 见下面例子 .ccc(@"Objective-C").ddd(NO)
- (ClassB * (^)(NSString *))ccc
{
return^(NSString *str) {
//code
NSLog(@"%@", str);
ClassB* b = [[ClassB alloc] initWithString:ccc];
returnb;
}
}
//------------------------------------------
@interface ClassB : NSObject
@property(nonatomic, readonly) ClassB *(^ddd)(BOOL enable);
- (id)initWithString:(NSString *)str;
@implement ClassB
- (ClassB *(^)(BOOL))ddd
{
return^(BOOL enable) {
//code
if(enable) {
NSLog(@"ClassB yes");
}else{
NSLog(@"ClassB no");
}
returnself;
}
}
// 最后我们可以这样做
id a = [ClassAnew];
a.aaa(YES).bbb(@"HelloWorld!").ccc(@"Objective-C").ddd(NO)