本篇文章主要讲一下ReactiveSwift中的核心元件:
- Event
- Observer
- Signal
1. Event
一个按钮被按下了、调用API接收到了一条信息或是一次长时间操作的完成,都会产生了Event
,并通过信号发送它们给了观察者,每个信息的载体(value/error)对应的是一个枚举Event:
public enum Event {
/// A value provided by the signal.
case value(Value)
/// The signal terminated because of an error. No further events will be
/// received.
case failed(Error)
/// The signal successfully terminated. No further events will be received.
case completed
/// Event production on the signal has been interrupted. No further events
/// will be received.
///
/// - important: This event does not signify the successful or failed
/// completion of the signal.
case interrupted
}
Note:
interrupted
表示事件被打断, 除非你去订阅一个已经无效的信号, 否则这个状态不会出现,当信号发送非Value的Event时, 那么这个信号就无效了. 无效的原因可能是failed, completed, interrupted。
2. Observer
An Observer is a simple wrapper around a function which can receive Events.
Observer
可以是任意东西,只要它正在等待或者即将等待信号中的事件。在 RAC中,它是通过使用基于闭包的 Signal.observe
方式或者是 SignalProducer.start
方式隐式创建的,Observer
封装了Event的处理逻辑,能接收Events:
public final class Observer {
public typealias Action = (Event) -> Void
private let _send: Action
/// Whether the observer should send an `interrupted` event as it deinitializes.
private let interruptsOnDeinit: Bool
internal init(action: @escaping Action, interruptsOnDeinit: Bool) {
self._send = action
self.interruptsOnDeinit = interruptsOnDeinit
}
public init(_ action: @escaping Action) {
self._send = action
self.interruptsOnDeinit = false
}
public func send(_ event: Event) {
_send(event)
}
public func send(value: Value) {
_send(.value(value))
}
public func send(error: Error) {
_send(.failed(error))
}
public func sendInterrupted() {
_send(.interrupted)
}
}
分析源码可以看出,Observer
内部有一个处理Event的闭包_send
,在初始化Observer
的时候就是给这个闭包赋值,而调用Observer.send
则是在执行这个闭包。
有了信息的载体和信息的处理逻辑, 接下来需要的是将信息发送出去:Signal。
3. Signal
Signal是热信号,会主动将产出的事件Event向外发送,而不会等到有人订阅后才开始发送,Signal
源码包含一个Core
属性,Signal只是Core的一个壳,所以我们主要分析Core
的源码:
private let core: Core
private final class Core {
private let disposable: CompositeDisposable
private let stateLock: Lock
private let sendLock: Lock
private var state: State
......
}
private enum State {
case alive(Bag<Observer>, hasDeinitialized: Bool)
case terminating(Bag<Observer>, TerminationKind)
case terminated
}
Core
里面最重要的属性就是State
,State
的作用有两个:
- 指示信号的状态。
- 保存信号订阅者添加进来的Observer对象。
那Observer
对象是怎么被添加进来的呢?先看下源码:
fileprivate func observe(_ observer: Observer) -> Disposable? {
var token: Bag<Observer>.Token?
stateLock.lock()
//1.信号处于state.alive状态,将新的observer对象添加到state.alive的数组中
if case let .alive(observers, hasDeinitialized) = state {
var newObservers = observers
token = newObservers.insert(observer)
self.state = .alive(newObservers, hasDeinitialized: hasDeinitialized)
}
stateLock.unlock()
//2. 如果1顺利执行,token会被赋值(即信号处于alive状态) 返回一个Disposable对象 否则直接向observer对象发 送interrupted事件
if let token = token {
return AnyDisposable { [weak self] in
self?.removeObserver(with: token)
}
} else {
observer.sendInterrupted()
return nil
}
}
从源码我们可以看出,通过observe
方法添加并保存了Observer(也就是保存了Event的处理逻辑),接下来需要的就是在合适的时机执行这些Observer内部的处理逻辑,就要通过调用Core.send(_ event: Event)
方法,具体看以下源码:
private func send(_ event: Event) {
if event.isTerminating { // 收到非Value的Event,信号状态从.alive切换到.terminating
self.stateLock.lock()
// 将.alive中的Observer数组移到.terminating中,遍历. terminating的数组observers,调用send函数
if case let .alive(observers, _) = state {
self.state = .terminating(observers, .init(event))
self.stateLock.unlock()
} else {
self.stateLock.unlock()
}
tryToCommitTermination()
} else { // 收到Value的Event
self.sendLock.lock()
self.stateLock.lock()
//遍历.alive的数组observers,调用send函数
if case let .alive(observers, _) = self.state {
self.stateLock.unlock()
for observer in observers {
observer.send(event)
}
} else {
self.stateLock.unlock()
}
self.sendLock.unlock()
stateLock.lock()
//遍历. terminating的数组observers,调用send函数
if case .terminating = state {
stateLock.unlock()
tryToCommitTermination()
} else {
stateLock.unlock()
}
}
}
private func tryToCommitTermination() {
...lock部分代码 略
if case let .terminating(observers, terminationKind) = state {
//切换状态到.terminated,遍历. terminating的数组observers,调用send函数
state = .terminated
if let event = terminationKind.materialize() {
for observer in observers {
observer.send(event)
}
}
}
}
有关信号状态的切换state
,它确切来说是一个枚举:
private enum State {
case alive(Bag<Observer>, hasDeinitialized: Bool)
case terminating(Bag<Observer>, TerminationKind)
case terminated
......
}
其中,状态terminated是不带关联数组的,这意味着当信号切换到terminated状态时,那么那些被保存的Observer对象也就跟着释放了,所以当不再需要使用信号时,应该向信号发送一个非Value事件确保资源释放。
那有了Observer的添加,Observer.send的执行, 再通过Signal.pipe()
方法创建一个热信号将这一切连接起来了,这个函数会返回一个元组, 元组的第一个值是output(类型为Signal), 第二个值是input(类型为Observer). 我们通过output来订阅信号, 通过input来向信号发生信息。
public static func pipe(disposable: Disposable? = nil) -> (output: Signal, input: Observer) {
var observer: Observer!
let signal = self.init { innerObserver, lifetime in
observer = innerObserver
lifetime += disposable
}
return (signal, observer)
}
//Signal.init()
public init(_ generator: (Observer, Lifetime) -> Void) {
core = Core(generator)
}
//Core.init()
fileprivate init(_ generator: (Observer, Lifetime) -> Void) {
//1. 设置信号初始状态为alive 同时初始化alive中的数组
state = .alive(Bag(), hasDeinitialized: false)
......
//2. 创建一个Observer对象并将该对象的_send闭包设置为Core.send函数
generator(Observer(action: self.send, interruptsOnDeinit: true), Lifetime(disposable))
}
从源码可以看出, pipe()
函数会通过一个generator: (Observer, Lifetime)
闭包去创建Core对象, 然后通过这个Core对象去创建Signal,pipe()
函数通过generator闭包捕获了Core.init()
中的innerObserver
对象, 而这个InnerObserver
对象的_send
指向的其实是Core.send
函数. 最后pipe()
将返回Signal和InnerObserver。
所以,pipe().output
(即Signal)的作用是管理信号状态并保存由订阅者提供的Observer对象, 而pipe().input
(即InnerObserver)的作用则是在接收到Event后依次执行这些被保存的Observer._send
。
上面的流程可以表示如下:
上面我们分析了Signal源码,接下来我们来具体创建一下Signal,对它进行使用。
Signal的使用
上面讲过,通过Signal.pipe()
函数会返回一个元组,元组的第一个值是output(类型为Signal),第二个值是input(类型为Observer),我们通过output来订阅信号, 通过input来向信号发生信息。
let signalTuple = Signal<Int, NoError>.pipe()
let (signal, observer) = Signal<Int, NoError>.pipe()
我们在viewDidLoad
中创建一个热信号,并发送数据:
typealias NSignal<T> = ReactiveSwift.Signal<T, NoError>
override func viewDidLoad() {
super.viewDidLoad()
//创建signal(output)和innerObserver(input)
let (signal, innerObserver) = NSignal<Int>.pipe()
signal.observeValues { (value) in //创建Observer并添加到Signal中
print("did received value: \(value)")
}
signal.observeValues { (value) in //再次创建Observer并添加到Signal中
print("did received value: \(value)")
}
innerObserver.send(value: 1)
innerObserver.sendCompleted()
}
//输出结果: did received value: 1
did received value: 1
Signal.observeValues
,是Signal.observe
的一个便利函数, 作用是创建一个只处理Value事件的Observer并添加到Signal中, 类似的还有只处理Failed事件的Signal.observeFailed和所有事件都能处理的Signal.observeResult。
再来看一个ViewModel中的Demo:
typealias NSignal<T> = ReactiveSwift.Signal<T, NoError>
//ViewModel.swift
class ViewModel {
let signal: NSignal<Int>
let innerObserver: NSignal<Int>.Observer
init() { (signal, innerObserver) = NSignal<Int>.pipe() }
}
//View1.swift
class View1 {
func bind(viewModel: ViewModel) {
viewModel.signal.observeValues { (value) in
print("View1 received value: \(value)")
}
}
}
//View2.swift
class View2 {
func bind(viewModel: ViewModel) {
viewModel.signal.observeValues { (value) in
print("View2 received value: \(value)")
}
}
}
//View3.swift
class View3 {
func bind(viewModel: ViewModel) {
viewModel.signal.observeValues { (value) in
print("View3 received value: \(value)")
}
viewModel.signal.observeInterrupted {
print("View3 received interrupted")
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
let view1 = View1()
let view2 = View2()
let view3 = View3()
let viewModel = ViewModel()
view1.bind(viewModel: viewModel)//订阅时机较早
viewModel.innerObserver.send(value: 1)
view2.bind(viewModel: viewModel)//订阅时机较晚
viewModel.innerObserver.send(value: 2)
viewModel.innerObserver.sendCompleted()//发送一个非Value事件 信号无效
view3.bind(viewModel: viewModel)//信号无效后才订阅
viewModel.innerObserver.send(value: 3)//信号无效后发送事件
}
输出: View1 received value: 1
View1 received value: 2
View2 received value: 2
View3 received interrupted
view2的订阅时间晚于value1的发送时间,所以view2收不到value1对应的事件,而之后发送一个非Value的事件后,信号便无效了。所以虽然view1和view2的订阅都早于value3的发送时间,但因为value3在信号发送前先发送了completed,结果就是view1和view2都不会收到value3事件,当然view3也不会收到value3事件,它只会收到一个interrupted。