之前在探索RxSwift源碼的時候,發(fā)現(xiàn)幾個地方都有循環(huán)引用荐健,但那是故意的酱畅,而我們使用RxSwift的時候,如果循環(huán)引用就不好說故意了江场。那現(xiàn)在根據(jù)RxSwift核心邏輯和銷毀流程的探索纺酸,把RxSwift的引用關(guān)系捋一捋:
1. Observable<Any>.create{ self }
self.observable = Observable<Any>.create { (anyObserver) -> Disposable in
print(self) //循環(huán)引用1
anyObserver.onNext("保存了observable")
anyObserver.onCompleted()
return Disposables.create()
}
- 引用關(guān)系
self
->
AnonymousObservable
->
SubscribeHandler
->
self
所以如果不保存observable
是沒有循環(huán)引用的:
let observable = Observable<Any>.create { (anyObserver) -> Disposable in
print(self) //沒有循環(huán)引用
anyObserver.onNext("不保存observable")
anyObserver.onCompleted()
return Disposables.create()
}
2. observable.subscribe { self }
let observable = Observable<Any>.create { (anyObserver) -> Disposable in
anyObserver.onNext("沒有使用weak")
anyObserver.onCompleted()
return Disposables.create()
}
let dispose = observable.subscribe { (text) in
print(self) //循環(huán)引用2
}
dispose.disposed(by: self.disposbag)
- 引用關(guān)系
self
->
DisposeBag
->
BinaryDisposable
->
SinkDisposer
->
AnonymousObservableSink
->
AnonymousObserver
->
EventHandler
->
onNext
->
self
所以使用時要用weak
:
let observable = Observable<Any>.create { (anyObserver) -> Disposable in
anyObserver.onNext("使用weak修飾")
anyObserver.onCompleted()
return Disposables.create()
}
let dispose = observable.subscribe {[weak self] (text) in
print(self) //沒有循環(huán)引用
}
dispose.disposed(by: self.disposbag)
3. Disposables.create{ self }
第一種情況
self.observable = Observable<Any>.create { (anyObserver) -> Disposable in
anyObserver.onNext("保存了observable")
anyObserver.onCompleted()
return Disposables.create{
print(self) //循環(huán)引用
}
}
- 引用關(guān)系
self
->
AnonymousObservable
->
SubscribeHandler
->
AnonymousDisposable
->
DisposeAction
->
self
所以使用時可以不保存observable
或者使用weak
:
let observable = Observable<Any>.create { (anyObserver) -> Disposable in
anyObserver.onNext("沒有保存observable")
anyObserver.onCompleted()
return Disposables.create{
print(self) //沒有循環(huán)引用
}
}
self.observable = Observable<Any>.create {[weak self] (anyObserver) -> Disposable in
anyObserver.onNext("使用weak修飾")
anyObserver.onCompleted()
return Disposables.create{
print(self) //沒有循環(huán)引用
}
}
第二種情況
let observable = Observable<Any>.create { (anyObserver) -> Disposable in
anyObserver.onNext("不發(fā)送完成事件")
return Disposables.create{
print(self) //循環(huán)引用
}
}
let dispose = observable.subscribe { (text) in
print("收到響應(yīng)")
}
dispose.disposed(by: self.disposbag)
- 引用關(guān)系
self
->
DisposeBag
->
BinaryDisposable
->
SinkDisposer
->
AnonymousDisposable
->
DisposeAction
->
self
想要釋放要發(fā)送完成事件:
let observable = Observable<Any>.create { (anyObserver) -> Disposable in
anyObserver.onNext("發(fā)送完成事件")
anyObserver.onCompleted()
return Disposables.create{
print(self) //沒有循環(huán)引用
}
}
let dispose = observable.subscribe { (text) in
print("收到響應(yīng)")
}
dispose.disposed(by: self.disposbag)
補充
- 有時項目復(fù)雜起來很難找到哪里出問題,為此RxSwift有自己的引用計數(shù):
使用之前址否,需要先在podfile上添加并執(zhí)行pod install:
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.name == 'RxSwift'
target.build_configurations.each do |config|
if config.name == 'Debug'
config.build_settings['OTHER_SWIFT_FLAGS'] ||= ['-D', 'TRACE_RESOURCES']
end
end
end
end
end
接著直接獲取現(xiàn)有計數(shù)餐蔬,來判斷是否釋放完全,如果釋放完全計數(shù)為0:
RxSwift.Resources.total