RxSwift 的資源管理
關於 RxSwift 的記憶體管理機制
在介紹關於 RxSwift 基本入門 中提到了一些
RxSwift
的核心概念 -Observable
,我們描述了事件訊息的種類,分別是 :next
、error
、completed
, 當這個Observable
收到error
跟completed
事件訊息時,那麼這個Observable
將不會再接受其他的訂閱事件。 同時在這邊用來分派給此Observable
的記憶體資源就一起被釋放掉了,我們可以將其視為類似ARC
的自動記憶體釋放。 如果你想立刻將Observable
關閉且立刻釋放資源,那麼你需要呼叫dispose
函數,這邊我們可以理解為類似MRC
的手動釋放。
如果一個 Observable
在一定的時間內結束,即使不呼叫 dispose
或者使用 DisposeBag
也不會引發 Memory Leak
。 如果一個 Observable
因為某些原因
沒有結束,那記憶體將會永遠的不會被釋放,所以就算 根據 Observable
的運作原理,我們也會希望透過某些記憶體回收機制來確保不會產生 Memory Leak
的問題。
下面將詳細介紹幾種 RxSwift
的記憶體管理機制。
Disposing
在一開始提到的,我們可以呼叫 dispose
方法,去直接關閉這個 Observable
。
下面是一個簡單的例子 :
1 | let subscription = Observable<Int>.interval(0.3, scheduler: scheduler) |
Result :
1 | 0 |
不過這並不是一個好方法,手動呼叫 dispose
是一種不太好的編程習慣。更好的方法是使用像是 DisposeBag
或者一些其他的機制。
如果在dispose
被執行之後,還會繼續執行 subscribe
中的代碼片段嗎 ? 像是在這個範例中,還會繼續 print
東西嗎 ? 答案是 : 不一定 。
要視 scheduler 被訂閱時所在的執行緒以及 dispose 呼叫的執行緒 而定。
如果 scheduler
是一個 serial scheduler
,例如 : MainScheduler
並且 dispose 在同一個 serial scheduler
被呼叫,答案是不會,否則答案是會的。
關於 RxSwift
的 scheduler
我們會在後面做更詳細的討論,假如你真的需要呼叫 dispose
,那麼我們為了避免出現上述的狀況,我們必須詳細的告訴 Observable
訂閱的 scheduler
執行緒以及確保 dispose
呼叫的方法在同一執行緒。
1 | //observeOn on MainScheduler(main thread) |
這樣就能確保在 dispose
之後不會在 print 出任何訊息了。
Dispose Bags
Dispose Bag
在 RxSwift
中的作用與 ARC
類似。它就像是一個 autoreleasepool
一樣。當 disposeBag
被銷毀時,同時銷毀被加入這個 disposeBag
的 Observable
。
基本的 disposeBag 使用方法。
1 | let disposeBag = DisposeBag() |
當 disposeBag
的 scope
結束時,就會呼叫解構子,當 Dispose Bag
的解構子被呼叫的時候,他會對每個 Observable
呼叫 dispose
方法。
如果你需要馬上清除記憶體,你可以立刻創建一個新的
DisposeBag
1 | self.disposeBag = DisposeBag() |
如果需要顯式的手動清理資源,那麼需要使用
CompositeDisposable
。
Take until
另外一種自動管理機制則是使用 takeUntil
1 | sequence |
以上就是關於 RxSwift
的記憶體管理機制。這次介紹就到這邊結束,希望能讓大家對於 RxSwift
有更深一步的認識。