可被清除的资源Disposable
是RxSwift
的核心成员之一,它主要是用来清除再也不须要的资源。那么下面来探索一下RxSwift
是怎样管理这些资源的生命周期呢。 api
error
或者 completed
事件,那么全部内部资源都会被释放,不须要咱们手动释放。Disposable
) 调用 dispose
方法。DisposeBag
)来管理订阅的生命周期,通常是把资源加入到一个全局的DisposeBag
里面,它跟随着页面的生命周期,当页面销毁时DisposeBag
也会随之销毁,同时DisposeBag
里面的资源也会被一一释放。var disposeBag = DisposeBag() // 来自父类 ViewController
override func viewDidLoad() {
super.viewDidLoad()
...
usernameValid
.bind(to: passwordOutlet.rx.isEnabled)
.disposed(by: disposeBag)
usernameValid
.bind(to: usernameValidOutlet.rx.isHidden)
.disposed(by: disposeBag)
}
复制代码
下面这一段代码是常规的建立一个序列,而后订阅,最后手动销毁的流程。安全
let observable = Observable<Any>.create { (observer) -> Disposable in
observer.onNext("七夕快乐")
return Disposables.create {
print("销毁释放了")
}
}
let dispose = observable.subscribe(onNext: { (message) in
print("有一条新消息:\(message)")
}, onError: { (error) in
print("错误")
}, onCompleted: {
print("完成")
}) {
print("销毁回调")
}
print("开始调用dispose")
dispose.dispose()
复制代码
执行结果:
有一条新消息:七夕快乐
开始调用dispose
销毁释放了
销毁回调
复制代码
Observable<Any>.create
方法有一个尾随闭包,须要返回一个实现了Disposable
协议的实例。Disposables.create
方法里面看看extension Disposables {
public static func create(with dispose: @escaping () -> Void) -> Cancelable {
return AnonymousDisposable(disposeAction: dispose)
}
}
复制代码
AnonymousDisposable
对象并返回,很明显,这是一个匿名销毁者,跟建立序列的时候会建立一个匿名序列实现方式很是类似。fileprivate final class AnonymousDisposable : DisposeBase, Cancelable {
public typealias DisposeAction = () -> Void
private let _isDisposed = AtomicInt(0)
private var _disposeAction: DisposeAction?
public var isDisposed: Bool {
return isFlagSet(self._isDisposed, 1)
}
fileprivate init(_ disposeAction: @escaping DisposeAction) {
self._disposeAction = disposeAction
super.init()
}
fileprivate init(disposeAction: @escaping DisposeAction) {
self._disposeAction = disposeAction
super.init()
}
fileprivate func dispose() {
if fetchOr(self._isDisposed, 1) == 0 {
if let action = self._disposeAction {
self._disposeAction = nil
action()
}
}
}
}
复制代码
dispose
方法,fetchOr(self._isDisposed, 1) == 0
这行代码是控制if语句里面只会进去一次。fetchOr
方法的具体实现:AtomicInt
是继承NSLock
,在更改value
值的时候加了一把锁,保证线程安全,而后运用了或运算并保存结果。位运算更加的高效。self._disposeAction
赋值给临时变量action
,而后置空self._disposeAction
,再执行action()
。这样操做的缘由是若是_disposeAction
闭包是一个耗时操做,也可以保证_disposeAction
可以当即释放。func fetchOr(_ this: AtomicInt, _ mask: Int32) -> Int32 {
this.lock()
let oldValue = this.value
this.value |= mask
this.unlock()
return oldValue
}
复制代码
final class AtomicInt: NSLock {
fileprivate var value: Int32
public init(_ value: Int32 = 0) {
self.value = value
}
}
复制代码
_subscriberHandle
里面,其实这个流程以前还有一个很是重要的流程:订阅,进入到observable.subscribe
方法public func subscribe(onNext: ((Element) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
-> Disposable {
let disposable: Disposable
if let disposed = onDisposed {
disposable = Disposables.create(with: disposed)
}
else {
disposable = Disposables.create()
}
let observer = AnonymousObserver<Element> { event in
switch event {
case .next(let value):
onNext?(value)
case .error(let error):
if let onError = onError {
onError(error)
}
else {
Hooks.defaultErrorHandler(callStack, error)
}
disposable.dispose()
case .completed:
onCompleted?()
disposable.dispose()
}
}
return Disposables.create(
self.asObservable().subscribe(observer),
disposable
)
}
复制代码
Disposable
对象,并保存了销毁回调闭包,当执行销毁时,会把消息回调出去disposable.dispose()
,这就证明了前面说的:一个序列若是发出了 error
或者 completed
事件,那么全部内部资源都会被释放,不须要咱们手动释放。return Disposables.create( self.asObservable().subscribe(observer), disposable )
,这里返回的Disposable
对象就是咱们外面手动调用dispose.dispose()
方法的dispose
对象,或者说是加入到全局的DisposeBag
的销毁者。public static func create(_ disposable1: Disposable, _ disposable2: Disposable) -> Cancelable {
return BinaryDisposable(disposable1, disposable2)
}
复制代码
func dispose() {
if fetchOr(self._isDisposed, 1) == 0 {
self._disposable1?.dispose()
self._disposable2?.dispose()
self._disposable1 = nil
self._disposable2 = nil
}
}
复制代码
dispose()
时会把2个销毁者分别销毁self.asObservable().subscribe(observer)
的返回值是什么。来到Producer
类的subscribe
方法let disposer = SinkDisposer()
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
复制代码
SinkDisposer
对象并返回,因此前面建立二元销毁者的第二个参数就是它。通过以前对RxSwift
核心逻辑的分析文章,咱们知道sink是链接序列和观察者的桥梁,当sink销毁后,序列和观察者之间就没法通信了。self.run(observer, cancel: disposer)
override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
let subscription = sink.run(self)
return (sink: sink, subscription: subscription)
}
复制代码
AnonymousObservableSink
对象,并保存了上一步建立的SinkDisposer
对象。在AnonymousObservableSink
的源码里面发现on
方法中,当发出完成和错误信号后,会当即执行dispose
进行销毁,因此一旦咱们的序列发出完成或者错误信号后就没法再次响应了!sink.run(self)
,方法里面执行的是parent._subscribeHandler(AnyObserver(self))
,_subscribeHandler
闭包就是外面建立序列Observable<Any>.create
的尾随闭包,因此返回值就是Disposables.create {print("销毁释放了")}
。setSinkAndSubscription
方法func setSinkAndSubscription(sink: Disposable, subscription: Disposable) {
self._sink = sink
self._subscription = subscription
let previousState = fetchOr(self._state, DisposeState.sinkAndSubscriptionSet.rawValue)
if (previousState & DisposeState.sinkAndSubscriptionSet.rawValue) != 0 {
rxFatalError("Sink and subscription were already set")
}
if (previousState & DisposeState.disposed.rawValue) != 0 {
sink.dispose()
subscription.dispose()
self._sink = nil
self._subscription = nil
}
}
复制代码
sink
和 subscription
,就是上一步返回的销毁者和AnonymousObservableSink
对象,AnonymousObservableSink
里面保存了sink的销毁者SinkDisposer
dispose()
而后置空 nil
dispose.dispose()
销毁时销毁的究竟是什么呢func dispose() {
let previousState = fetchOr(self._state, DisposeState.disposed.rawValue)
if (previousState & DisposeState.disposed.rawValue) != 0 {
return
}
if (previousState & DisposeState.sinkAndSubscriptionSet.rawValue) != 0 {
sink.dispose()
subscription.dispose()
self._sink = nil
self._subscription = nil
}
}
复制代码
dispose()
,咱们查看 dispose()
得出: 就是把初始化的时候保存的两个属性进行销毁而后置空。RxSwift
中,sink
存放了序列和观察者,来创建它们之间的响应关系,当把序列和观察者之间的桥梁sink
销毁了,也就断开了它们之间的响应关系,从而没法再接收到消息。error
或者 completed
事件,那么全部内部资源都会被释放,不须要咱们手动释放。disposeBag
,是在disposeBag
对象销毁时,依次销毁里面存储的东西