ReactorKit源码阅读

栏目: IOS · 发布时间: 7年前

内容简介:为了让Swift的例如给

ReactorKit 是建立在 RxSwift 生态下的一个状态管理框架,说是框架,其实它的封装非常轻量。本文是阅读源码的一些收获。

2. 协议和运行时

为了让Swift的 protocol extension 具有 给实现协议的人动态添加一个属性(依赖) 这个能力,它采用了 runtime 的实现方式。

例如给 Reactor协议 添加一个 disposeBag 变量:

protocol Reactor { ... }
extension Reactor {
    fileprivate var disposeBag: DisposeBag {
        get { return self.associatedObject(forKey: &disposeBagKey, default: DisposeBag()) }
    }
}
复制代码

最终调用的是:

objc_setAssociatedObject(self, key, object, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
复制代码

3. 谁来处理副作用

对于一个函数式框架来说,这点至关重要。比如 Flux 是通过 ActionCreatorRedux 是由 Middlewares 来真正处理这些对外界环境的不纯函数(脏活累活)。

ReactorKit 这边是由 Reactor 里的 mutate() 函数来处理副作用的。

func mutate(action: Action) -> Observable<Mutation>
复制代码

需要注意的是,由于他的返回值是 Observable ,这意味着在 Action 转换到 Mutation 的过程中,可以 异步 执行副作用来获取结果(比如网络请求,数据库操作)。

4. 如何修改内部状态(State)

Reactor 的核心方法(也是最长的)就是:

func createStateStream() -> Observable<State> 
复制代码

Reactor内声明的大多数函数都在此方法被调用,状态就是在这个方法内最终被改变的。

具体看一下他是怎么做到的:

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】Observable<Action>
  • 【Action】 放到 transform() 函数中,给用户时机改变其序列类型
  • 【Action】 于是得到了转换过的 Observable<Action> ,记作 transformedAction
  • 【Action 绑定 (Action) -> Mutation】transformedAction 绑定(flatMap)到 mutate() 函数上, mutate() 的签名是 (Action) -> Observable<Mutation> ,用户的副作用在绑定过程中执行。
  • 【Mutation】 于是得到新的序列,类型为 Observable<Mutation> ,意味着用户已经把数据拿到,一切就位。
  • 【Mutation】 放到 transform() 函数中,给用户时机改变其序列类型
  • 【Mutation】 于是得到了转换过的 Observable<Mutation> ,记作 transformedMutation
  • 【(State, Mutation) -> State】 即执行 reduce() 方法,通过 scan 函数让 mutation 可以不断作用到 state
  • 【State】 得到结果 Observable<State>
  • 【State】 放到 transform() 函数中,给用户时机改变其序列类型
  • 【State】 于是得到了转换过的 Observable<State> ,记作 transformedState
  • 【State】 顺便修改内部的 currentState
  • 【State】 返回最终结果
ReactorKit源码阅读

这个过程结合这个图看就更加清晰,这个函数(也是整个Reactor)的作用就是要做这么一件事: Action->Mutation->State


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Single Page Web Applications

Single Page Web Applications

Michael Mikowski、Josh Powell / Manning Publications / 2013-9-30 / USD 44.99

Code for most web sites mostly runs on the server. When a user clicks on a link, the site reacts slowly because the browser sends information to the server and the server sends it back again before di......一起来看看 《Single Page Web Applications》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换