lufei's Studio.

iOS 优雅的实现数据绑定

字数统计: 433阅读时长: 1 min
2022/01/19 Share

前言

如果你想设计一个 MVVM 架构的新项目,那么如何实现数据绑定,是一个需要关心的问题。

当然,如果你非要使用 Delegate 或者 Notification 去做的话,其实也没问题,但我想,这应该都不算优雅的方式。

数据绑定的成熟方案,有比如 RXSwift,KVO 等等,感兴趣的朋友可以去搜索一下,但是,假如你在使用 Swift,事实上有一个现成的被遗忘的方案,那就是 Swift 中无所不能的闭包

实现

说再多也没用,直接上代码,实现一个 Box

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
final class Box<T> {
// 声明一个别名
typealias Listener = (T) -> Void
var listener: Listener?

var value: T

var wrappedValue: T {
set {
value = newValue
listener?(value)
}
get {
return value
}
}

init(_ value: T){
self.value = value
}

func bind(listener: Listener?) {
self.listener = listener
listener?(value)
}
}

大功告成

如何使用

假如我们的 ViewController 有一个 UILabel 是这样的

1
2
3
4
5
6
7
lazy var label:UILabel = {
let label = UILabel()
label.textColor = .red
label.textAlignment = .center
label.frame = view.bounds
return label
}()

我们需要在加载一个延时任务后,去更新它,在 MVVM 的架构下,我们可以这么做:

先简单实现一个 ViewModel,大概是这样

1
2
3
4
5
6
7
8
9
10
class ViewModel {
var texts: Box<String> = Box("")
func fetchData() {
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 2) {
DispatchQueue.main.async {
self.texts.wrappedValue = "lufei"
}
}
}
}

然后在 ViewController 中做一下数据绑定

1
2
3
4
viewModel.texts.bind { [weak self](value) in
guard let self = self else {return}
self.label.text = value
}

最后在你觉得合适的时机拉取数据

1
viewModel.fetchData()

然后整段代码就变得格外优雅起来了,心情也会变成一样的~

CATALOG
  1. 1. 前言
  2. 2. 实现
  3. 3. 如何使用