关于 ios:RxSwift: 当一个类有 disposeBag 属性时总是使用 [unowned self] 是否安全?

RxSwift: Is it safe to always use [unowned self] when a class has a disposeBag property?

我最近发现一篇文章说,只要您将订阅添加到 DisposeBag 并且它位于视图控制器内,使用 [unowned self] 总是安全的。

假设我有一个 ViewController,其中 deinit 由于强引用而没有被调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class ViewController: UIViewController {

    @IBOutlet weak var searchBar: UISearchBar!
    @IBOutlet weak var tableView: UITableView!

    private let disposeBag = DisposeBag()
    private var results = Variable<[Item]>([])
    private var searchText = Variable("")
    var selectedCompletion: ((Item) -> Void)!

    override func viewDidLoad() {
        super.viewDidLoad()
        results.asObservable()
            .bind(to: tableView.rx.items(cellIdentifier:"CustomCell", cellType: CustomCell.self)) { row, item, cell in
                cell.configure(with: item)
            }
            .disposed(by: disposeBag)

        tableView.rx.itemSelected
            .subscribe(onNext: { ip in
                self.selectedCompletion(self.results.value[ip.row])
                self.navigationController?.popViewController(animated: true)
            })
            .disposed(by:disposeBag)

        searchBar.rx.text
            .debounce(0.6, scheduler: MainScheduler.instance)
            .subscribe(onNext: { searchText in
                if searchText == nil || searchText!.isEmpty { return }
                self.search(query: searchText!)
            })
            .disposed(by: disposeBag)
    }

    private func search(query: String) {
        // Search asynchronously
        search(for: query) { response in

            // Some logic here...
            self.results.value = searchResult.results
        }
    }
}

我应该能够简单地在订阅闭包中声明 [unowned self],而不必担心我的应用会因 selfnil 而崩溃。

我感到困惑的是,因为搜索是异步的,这是否意味着如果 ViewController 在查询完成之前已从导航堆栈中弹出,那么 self 可以是 nil 吗?

或者 DisposeBag 会先被释放而闭包不会完成?

任何关于如何知道一个类是否拥有闭包的说明也很好。


根据我的经验,将 unowned 与处置袋一起使用是一种安全的方法,除了一个块 - onDisposed。有一些应用程序因为 unowed 关键字而崩溃的情况 -> weak 在这里很有用。


正如@kzaher 在github上所说的那样

you should never use unowned.

来源:

https://github.com/RxSwiftCommunity/RxDataSources/issues/169
https://github.com/ReactiveX/RxSwift/issues/1593