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 有更深一步的認識。