簡體   English   中英

RXSwift 閉包中的“[弱自我]”

[英]'[weak self]' in RXSwift closures

我需要在 RXSwift subscribeNext 閉包中使用[weak self]嗎?

我有代碼:

    searchController.searchBar.rx_text.throttle(0.2, scheduler: MainScheduler.instance).subscribeNext { searchText in
        self.viewModel.searchForLocation(searchText)
    }.addDisposableTo(DisposelBag.sharedDisposelBag.disposeBag)

我是否需要修改它以便在關閉開始時有一個[weak self]捕獲列表? 像這樣:

    searchController.searchBar.rx_text.throttle(0.2, scheduler: MainScheduler.instance).subscribeNext { [weak self] searchText in
        self?.viewModel.searchForLocation(searchText)
    }.addDisposableTo(DisposelBag.sharedDisposelBag.disposeBag)

如果閉包不歸類所有,則不必使用[weak self]

在內聯閉包的情況下,閉包不屬於類,而是屬於它所在的范圍,並且會在離開范圍時釋放。

如果閉包被傳入,它可能或可能不屬於類(例如一個屬性),並且謹慎使用[weak self]以防它歸類所有。

是的,如果您在閉包中訪問self ,您應該創建一個對self的弱捕獲,並且在調用閉包之前self可能變為nil

如果一個閉包捕獲self然后self變為nil ,當閉包被調用並試圖訪問那個self ,你會得到一個異常。

感謝 scotteg,他在 GitHub 上有一個示例項目: https : //github.com/scotteg/TestRxSwiftClosures

請參閱示例中的DetailViewController

您可以取消注釋其他兩個示例,一次一個,以查看結果。 第一個根本沒有定義捕獲列表,第二個定義了一個unowned捕獲。 運行應用程序並輸入一些文本並在 5 秒內點擊完成(每次關閉有 5 秒的延遲)。 前兩個示例將導致拋出異常。

基本規則是:如果捕獲(例如self )可以設置為nil ,例如如果它引用的實例被釋放,則將捕獲定義為weak 否則,如果該封內的封閉和捕獲會一直稱對方,並在同一時間被釋放,定義為捕捉unowned

如果存在強引用循環,您將需要使用[unowned self][weak self] 閉包內的變量可以被閉包“擁有”,並且如果閉包是的話,它就會一直存在,所以這就是我們做[unowned self][weak self]

[unowned self] 表示當block被調用時self不能為nil。如果block被調用並且self為nil,那么應用程序崩潰。

[weak self] 意味着當塊被調用時 self 可以為零。因此,您必須在塊內處理可選的 self 。

所以,我的快速回答是 1.當您在視圖控制器塊中引用視圖模型時,始終使用 [unowned self],因為您可以確保視圖模型始終存在於其關聯的視圖控制器中。

2.在其他情況下,當你在一個塊中使用 self 時總是被警告。根據 self 是否可以為 nil 來選擇 unowned 和 weak。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM