美文网首页
ReactorKit 粗略源码分析

ReactorKit 粗略源码分析

作者: 那个人一定不是我 | 来源:发表于2018-08-31 15:03 被阅读0次

    ReactorKit作为RxSwift的框架之一,如文档描述结合了Flux思想,行为单向性,Reactor只进行行为处理和状态改变通知。框架的主要成分为ActionStateMutation(对客户环境不可见)、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(继承了协议_ObjCStoryboardViewView)使ViewControllerviewDidLoad方法中调用View协议的方法func bind(reactor: Reactor)。在"ReactorKitRuntime.m"文件中,NSObject加载时通过Runtime交换ViewControllerviewDidLoad方法,并在中间执行ViewController_reactorkit_performBinding方法,在@objc func _reactorkit_performBinding()中调用了_ObjCStoryboardView协议方法performBinding,在StoryboardView的扩展中的performBinding方法调用了View的协议方法self.bind(reactor: reactor),让ViewControllerReactor进行处理。

    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进行装换后,通过flatMapAction传入到self.mutate方法,转换为Mutation序列mutation
    • mutation通过transform进行装换后,进行scan操作符将StateMutation传入到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 mutatefunc reduce方法,处理从ActionMutation,再到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时,才通知自己的订阅者有新的事件行为发生。

    相关文章

      网友评论

          本文标题:ReactorKit 粗略源码分析

          本文链接:https://www.haomeiwen.com/subject/inzrwftx.html