ReactorKit作为RxSwift的框架之一,如文档描述结合了Flux思想,行为单向性,Reactor
只进行行为处理和状态改变通知。框架的主要成分为Action
、State
、Mutation
(对客户环境
不可见)、func mutate
(Action -> Mutation)、func reduce
(通过Mutation更新State),它们都是由Reactor
类进行组合关联。注意:客户环境
的定义在上篇RxFeedback 粗略源码分析可见。下文中的大部分客服环境
可以看做为View实体
(··View 和 ··ViewController在框架内都指代为View实体
)或者ViewController
。框架内大部分成员读写都是通过AssociatedObject
方式进行处理。 现在从源码说起。
首先,要使用ReactorKit除了创建一个对应的Reactor
类外,还需要实现View
协议的View实体
,View
协议,如下:
public protocol View: class, AssociatedObjectStore {
associatedtype Reactor: _Reactor
var disposeBag: DisposeBag { get set }
var reactor: Reactor? { get set }
func bind(reactor: Reactor)
}
,定义两个成员和一个方法,后续将分析调用过程。框架提供了另一个协议StoryboardView
(继承了协议_ObjCStoryboardView
和View
)使ViewController
在viewDidLoad
方法中调用View
协议的方法func bind(reactor: Reactor)
。在"ReactorKitRuntime.m
"文件中,NSObject
加载时通过Runtime交换ViewController
的viewDidLoad
方法,并在中间执行ViewController
的_reactorkit_performBinding
方法,在@objc func _reactorkit_performBinding()
中调用了_ObjCStoryboardView
协议方法performBinding
,在StoryboardView
的扩展中的performBinding
方法调用了View
的协议方法self.bind(reactor: reactor)
,让ViewController
与Reactor
进行处理。
extension OSViewController {
@objc func _reactorkit_performBinding() {
(self as? _ObjCStoryboardView)?.performBinding()
}
}
.
下面具体分析self.bind(reactor: reactor)
背后的逻辑。在客户环境
中都是通过如下代码建立关联:
//Action
···btn.rx.tap
.map { Reactor.Action. ··· }
.bind(to: reactor.action)
.disposed(by: disposeBag)
// State
reactor.state.map { ··· }
.distinctUntilChanged()
.bind(to: ···)
.disposed(by: disposeBag)
点击事件通过map
处理,通知Action
事件给reactor.action
序列。reactor.action
的执行,在Reactor
基类里通过var action
属性获取到Action
序列_action
前,先进行了State
序列_state
的处理 _ = self._state
,如果不存在则创建,创建的代码为self.createStateStream()
。注意在createStateStream
函数中获取Action
序列是直接通过self._action
(同样不存在进行创建,但只是通过默认构造函数.init()
),避免通过self.action
造成循环引用。下面来看看框架的关联核心createStateStream
:
public func createStateStream() -> Observable<State> {
let action = self._action.asObservable()
let transformedAction = self.transform(action: action)
let mutation = transformedAction
.flatMap { [weak self] action -> Observable<Mutation> in
guard let `self` = self else { return .empty() }
return self.mutate(action: action).catchError { _ in .empty() }
}
let transformedMutation = self.transform(mutation: mutation)
let state = transformedMutation
.scan(self.initialState) { [weak self] state, mutation -> State in
guard let `self` = self else { return state }
return self.reduce(state: state, mutation: mutation)
}
.catchError { _ in .empty() }
.startWith(self.initialState)
.observeOn(MainScheduler.instance)
let transformedState = self.transform(state: state)
.do(onNext: { [weak self] state in
self?.currentState = state
})
.replay(1)
transformedState.connect().disposed(by: self.disposeBag)
return transformedState
}
- 首先获取
Action
可观察序列action
。 -
action
通过transform
进行装换后,通过flatMap
将Action
传入到self.mutate
方法,转换为Mutation
序列mutation
。 -
mutation
通过transform
进行装换后,进行scan
操作符将State
和Mutation
传入到self.reduce
方法,装换为State
序列state
。 -
state
通过transform
进行装换后,进行do
操作更新当前状态currentState
,在进行replay、connect
操作,此时State的序列创建完成,赋给_state
。
_ = self._state
则执行完毕,由于在createStateStream
中_action
已经创建,后面直接返回值。 到此,客户环境
中的reactor.action
执行完毕。如果客户环境
先执行的reactor.state.···
的调用,则直接调用的createStateStream
方法,Action
序列self._action
也同样被创建。
到此,Reactor
的状态序列和行为序列就创建完成,在客户环境
的func bind(reactor: ···)
方法中,就可以接收状态的改变和发起行为。在Reactor
的实现类中的func mutate
、func reduce
方法,处理从Action
到Mutation
,再到State
的转变。
另外,ActionSubject
作为Action的观察者,也是Action的可观察序列。在客户环境
通过事件发出Action,被ActionSubject监听到后,通过可观察序列的多次操作转换State的可观察序列, 最后通知到State的观察者。
ActionSubject
作为观察者的代码:
public func on(_ event: Event<Element>) {
···
if case .next = event {
self.observers.values.forEach {
$0(event)
}
}
···
}
,作为可观察序列被订阅的代码:
public func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == Element {
···
let key = self.nextKey
self.nextKey += 1
self.observers[key] = observer.on
···
}
,订阅者订阅ActionSubject
,它保存了订阅者的被通知方法observer.on
。当ActionSubject
自身被通知发生了Action
序列事件时,只在事件行为为.next
时,才通知自己的订阅者有新的事件行为发生。