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时,才通知自己的订阅者有新的事件行为发生。











网友评论