一、毁掉者

RxSwift毁掉者扮演了很重要的效果,毁掉已经完结(completed)的或许已经过错(error)的序列。可是假如你需求提前开释这些资源或许取消订阅的话,那么你可以对回来的Disposable(可被铲除的资源) 调用dispose办法。 调用dispose办法后,订阅将被取消,而且内部资源都会被开释掉。

1.毁掉者初探

接下来咱们来看一个比如:

        //创立序列
        self.intervalOB = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.init())
        //订阅事件-回来毁掉者
    let dispose = self.intervalOB.subscribe(onNext: { num in
      self.showSencondNum.text = String(num)
            print("num=\(num)")
    })
    _ = self.stopAction.rx.tap.subscribe(onNext: {
      print("点击按钮")
      dispose.dispose() //履行毁掉办法
    })

看到比如,1.创立了定时器序列 2.订阅并回来了Disposable(可被铲除的资源) 3.点击按钮履行dispose()毁掉办法。

运转结果:

iOS探索RxSwift之销毁者
咱们在看一个比如:

        // 创立序列
    let ob = Observable<Any>.create { observer -> Disposable in
      observer.onNext("NY")
      return Disposables.create { print("毁掉开释了") }
    }
    // 序列订阅
    let dispose = ob.subscribe(onNext: { anything in
      print("订阅到了:\(anything)")
    }, onError: { error in
      print("订阅到Error:\(error)")
    }, onCompleted: {
      print("完结了")
    }) {
      print("毁掉回调")
    }
    NSMutableArray(capacity: 10)//10 扩容10+10 上拉加载更多
    print("履行结束")
    dispose.dispose()

看到代码创立序列Observable 中回来了毁掉者Disposables.create,然后订阅ob回来Disposable(可被铲除的资源),在最后调用dispose.dispose()清理资源。

现在有一个问题Disposables.create回来的是什么?有什么效果?

进入代码一探终究:

iOS探索RxSwift之销毁者

iOS探索RxSwift之销毁者

public class DisposeBase {
  init() {
#if TRACE_RESOURCES
  _ = Resources.incrementTotal()
#endif
  }
 
  deinit {
#if TRACE_RESOURCES
  _ = Resources.decrementTotal()
#endif
  }
}
//协议类
public protocol Cancelable : Disposable {
  /// Was resource disposed.
  var isDisposed: Bool { get }
}
public protocol Disposable {
  /// Dispose resource.
  func dispose()
}
//在子类完成
/// Calls the disposal action if and only if the current instance hasn't been disposed yet.
  ///
  /// After invoking disposal action, disposal action will be dereferenced.
  fileprivate func dispose() {
    if fetchOr(self.disposed, 1) == 0 {
      if let action = self.disposeAction {
        self.disposeAction = nil
        action()
      }
    }
  }

AnonymousDisposable 根底了DisposeBase基类,并完成了Cancelable 协议办法isDisposed,dispose 。dispose 私有办法不可重写,保存临时action 并毁掉self.disposeAction = nil 在履行闭包action()。

继续跟踪代码:

func fetchOr(_ this: AtomicInt, _ mask: Int32) -> Int32 {
  this.lock()
  let oldValue = this.value
  this.value |= mask  // 0000 0000 | 0000 0001  结果是1
  this.unlock()
  return oldValue
}

判断self.disposed==0时履行并毁掉self.disposeAction。

2.毁掉的本质

咱们运转一下比如二:

iOS探索RxSwift之销毁者
从打印的信息上看出,订阅到了音讯,履行了履行结束后dispose.dispose(),在毁掉前履行了,开释后在履行了毁掉回调。

假如修改代码:

        // 创立序列
    let ob = Observable<Any>.create { observer -> Disposable in
      observer.onNext("NYY-e")
      observer.onCompleted()
      observer.onNext("XXXX")
      return Disposables.create { print("毁掉开释了") }
    }
        ////省掉代码............////
    print("履行结束")
        //    dispose.dispose()

从代码上看,onCompleted()后又再次,发送了音讯onNext(“XXXX”),假如onCompleted 履行完已经毁掉了序列,将看不到打印。

iOS探索RxSwift之销毁者
和咱们的猜想差不多,在onCompleted()之后序列履行完结Completed回调后,毁掉回调,在毁掉开释了。

问题1:
不履行dispose.dispose(),而履行observer.onCompleted() 的毁掉履行次序是不相同的。
问题2:
为什么会产生这样的差异,第一先履行开释,再毁掉回调。第二先回调,再开释。

进入源码一探终究:

iOS探索RxSwift之销毁者

    public static func create(_ disposable1: Disposable, _ disposable2: Disposable) -> Cancelable {
    BinaryDisposable(disposable1, disposable2)
  }
    //二元毁掉者
    private final class BinaryDisposable : DisposeBase, Cancelable {
  private let disposed = AtomicInt(0)
  // state
  private var disposable1: Disposable?
  private var disposable2: Disposable?
  /// - **returns**: Was resource disposed.
  var isDisposed: Bool {
    isFlagSet(self.disposed, 1)
  }
  /// Constructs new binary disposable from two disposables.
  ///
  /// - **parameter** disposable1: First disposable
  /// - **parameter** disposable2: Second disposable
  init(_ disposable1: Disposable, _ disposable2: Disposable) {
    self.disposable1 = disposable1
    self.disposable2 = disposable2
    super.init()
  }
  /// Calls the disposal action if and only if the current instance hasn't been disposed yet.
  ///
  /// After invoking disposal action, disposal action will be dereferenced.
  func dispose() {
    if fetchOr(self.disposed, 1) == 0 {
      self.disposable1?.dispose()
      self.disposable2?.dispose()
      self.disposable1 = nil
      self.disposable2 = nil
    }
  }
}

func dispose() 和AnonymousDisposable 的dispose 基本相同,也是只毁掉一次,可以外部调用。

return Disposables.create(
        self.asObservable().subscribe(observer),//SinkDisposer
        disposable //外界的毁掉闭包
   )

iOS探索RxSwift之销毁者

这个sinkAndSubscription.sink 和 sinkAndSubscription.subscription 的效果是什么?

iOS探索RxSwift之销毁者
sinkAndSubscription.sink 便是AnonymousObservableSink

sinkAndSubscription.subscription 便是 Disposable(毁掉者)目标处理闭包

所以毁掉Sink在Rx世界失掉联系,真正要毁掉的是RxSwift呼应式联系

3.垃圾袋毁掉流程

看垃圾袋代码:

extension Disposable {
  /// Adds `self` to `bag`
  ///
  /// - **parameter** bag: `DisposeBag` to add `self` to.
  public func disposed(by bag: DisposeBag) {
    bag.insert(self) //添加到垃圾袋
  }
}
private func _insert(_ disposable: Disposable) -> Disposable? {
    self.lock.performLocked {//递归
      if self.isDisposed {
        return disposable
      }
      self.disposables.append(disposable)
      return nil
    }
}
/// This is internal on purpose, take a look at `CompositeDisposable` instead.
  private func dispose() {
    let oldDisposables = self._dispose()
    for disposable in oldDisposables {  //遍历毁掉
      disposable.dispose()
    }
  }
    private func _dispose() -> [Disposable] {
    self.lock.performLocked {
      let disposables = self.disposables
      self.disposables.removeAll(keepingCapacity: false)//移除,不保存当前空间
      self.isDisposed = true //设置为已毁掉
      return disposables
    }
  }
  deinit {
    self.dispose() //类毁掉时调用
  }

DisposeBag->insert(序列)->dispose遍历履行(毁掉呼应联系)->先保存,在移除removeAll->设置isDisposed = true。

4.总结

  1. Disposable毁掉者:便是创立AnonymousDisposable中的dispose 基本相同,也是只毁掉一次,可以外部调用,sinkAndSubscription 在AnonymousDisposable 订阅中创立,sinkAndSubscription 控制毁掉,序列的呼应联系。
  2. DisposeBag垃圾袋:便是搜集和办理需求开释的序列,(添加到array,遍历开释)便是这样简略的逻辑。