前言
整个2017年我完全使用 Swift 进行开发了。使用 Swift 进行开发是一个很愉快的体验,我已经完全不想再去碰 OC 了。最近想做一个响应式编程的库,所以就把它拿来分享一下。
在缺乏好的资源的情况下,学习响应式编程成为痛苦。我开始学的时候,做死地找各种教程。结果发现有用的只是极少部分,而且这少部分也只是表面上的东西,对于整个体系结构的理解也起不了多大的作用。
Reactive Programing
说到响应式编程,ReactiveCocoa 和 RxSwift 可以说是目前 iOS 开发中最优秀的第三方开源库了。今天咱们不聊 ReactiveCocoa 和 RxSwif,咱们自己来写一个响应式编程库。如果你对观察者模式很熟悉的话,那么响应式编程就很容易理解了。
响应式编程是一种面向数据流和变化传播的编程范式。
比如用户输入、单击事件、变量值等都可以看做一个流,你可以观察这个流,并基于这个流做一些操作。“监听”流的行为叫做订阅。响应式就是基于这种想法。
废话不多说,撸起袖子开干。
我们以一个获取用户信息的网络请求为例:
func fetchUser(with id: Int, completion: @escaping ((User) -> Void)) {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+2) {
let user = User(name: "jewelz")
completion(user)
}
}
上面是我们通常的做法,在请求方法里传入一个回调函数,在回调里拿到结果。在响应式里面,我们监听请求,当请求完成时,观察者得到更新。
func fetchUser(with id: Int) -> Signal {}
发送网络请求就可以这样:
fetchUser(with: "12345").subscribe({
})
在完成 Signal 之前, 需要定义订阅后返回的数据结构,这里我只关心成功和失败两种状态的数据,所以可以这样写:
enum Result {
case success(Value)
case error(Error)
}
现在可以开始实现我们的 Signal 了:
final class Signal {
fileprivate typealias Subscriber = (Result) -> Void
fileprivate var subscribers: [Subscriber] = []
func send(_ result: Result) {
for subscriber in subscribers {
subscriber(result)
}
}
func subscribe(_ subscriber: @escaping (Result) -> Void) {
subscribers.append(subscriber)
}
}
写个小例子测试一下:
let signal = Signal()
signal.subscribe { result in
print(result)
}
signal.send(.success(100))
signal.send(.success(200))
// Print
success(100)
success(200)
我们的 Signal 已经可以正常工作了,不过还有很多改进的空间,我们可以使用一个工厂方法来创建一个 Signal, 同时将 send变为私有的:








