Swift & Objective-C 中的链式调用



Goku 的实现中,尝试了使用类似于 SnapKit 中,链式调用的方式,来构建 AlertView 的样式。具体使用如下

1
2
3
4
5
6
7
8
9
10
11
12
13
self.goku.presentAlert(animated: true, closure: { (make) in
make.theme
.actionSheet
.title("Okay/Cancel")
.message("A customizable action sheet message.")
.cancel("Cancel")
.destructive("OK")
.normal(["Button1", "Button2"])
.tapped({ (index) in
print("Tapped index is \(index)")
}
)
})

Swift 中的实现

查阅了 SnapKit 的源码

例如 make.top.equalTo(v2.snp.top).offset(50)

  • make 是 ConstraintMaker 的实例
  • top 是定义在 ConstraintMaker 中的一个 ConstraintMakerExtendable 类型的 public 变量,变量的调用,返回了该类的一个实例
  • equalTo 定义在 ConstraintMakerRelatable 类中,同时 ConstraintMakerExtendable 继承自该类,equalTo 定义如下,方法返回值是 ConstraintMakerEditable 的一个实例

    1
    public func equalTo(_ other: ConstraintRelatableTarget, _ file: String = #file, _ line: UInt = #line) -> ConstraintMakerEditable

SnapKit

Swift 中的链式很容易理解,总结下来其实是

理清继承关系,实例方法返回自身的实例。

Objective-C 中的实现

记得之前面试的时候,有个面试官问我有没有用 Objective-C 实现类似 swift 的函数式编程思想。当时就懵了!现在想想,应该类似于实现 链式调用

说实话 OC 的语法,在代码阅读方面实在不尽如人意。如果合理的应用 Block 到 OC 编程中,就能很好改善这样的问题,优点在于

  1. 可以作为类的属性被 . 出来
  2. 可以当作函数直接使用
1
2
3
4
5
6
7
8
9
10
11
12
LinkBlock.h

- (LineBlock *(^)(NSString *))say;

LinkBlock.m

- (LinkBlock *(^)(NSString *say))say {
return ^(NSString *say){
NSLog(@"Say %@", say);
return self;
};
}

调用方式只需要使用 LinkBlock 的实例,通过 .say(@"Hello") 就行。代码如下

1
2
3
LinkBlock *link = [[LinkBlock alloc] init];

link.say(@"Hello");

简单扩展一下

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
.h

@property(nonatomic, strong) NSMutableString *saySomething;
- (LinkBlock *)greet;
- (LinkBlock *(^)(NSString *))say;
- (LinkBlock *(^)(NSString *))to;

.m

- (instancetype)init {
if (self = [super init]) {
self.saySomething = [[NSMutableString alloc] init];
}
return self;
}

- (LinkBlock *)greet {
NSLog(@"Say \"%@\"", self.saySomething);
return self;
}

- (LinkBlock *(^)(NSString *say))say {
return ^(NSString *say){
[self.saySomething appendString: say];
return self;
};
}

- (LinkBlock *(^)(NSString *to))to {
return ^(NSString *to) {
[self.saySomething appendString:[NSString stringWithFormat:@" to %@", to]];
return self;
};
}

使用

1
meet.say(@"Nice to meet you").to(@"Jerry").greet;
Swift Extension 更新 fork 的 Git 仓库

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×