简体   繁体   English

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

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

I recently found an article that says using [unowned self] is always safe as long as you are adding the subscription to a DisposeBag and it is inside the view controller. 我最近发现一篇文章说,只要你将订阅添加到DisposeBag并且它在视图控制器中,使用[unowned self]总是安全的。

Assuming I have a ViewController where deinit is not being called due to a strong reference: 假设我有一个ViewController,由于强引用而没有调用deinit

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
        }
    }
}

I should simply be able to declare [unowned self] in my subscription closures and not have to worry about my app crashing from self being nil . 我应该简单地能够声明[unowned self]在我的订阅关闭,而不必担心我的应用程序崩溃self存在nil

Where I'm confused is, because search is asynchronous, doesn't that mean self can be nil if the ViewController has been popped off the navigation stack before the query completes? 我感到困惑的地方是,因为搜索是异步的,如果ViewController在查询完成之前弹出了导航堆栈,那么这是不是意味着self 可以 nil

Or would the disposeBag be deallocated first and the closure wouldn't complete? 或者, disposeBag是否会disposeBag被解除分配并且关闭不会完成?

Any clarification about how to know whether or not a class owns a closure would be great too. 关于如何知道一个类是否拥有一个闭包的任何澄清都会很棒。

In my experience it's a safe approach to use unowned with a dispose bag, except one block - onDisposed . 根据我的经验,除了一个块 - onDisposed之外,使用unowned包装袋的安全方法是一种安全的方法。 There have been the cases when an app crashed because of unowed keyword -> weak is useful here. 有些情况下应用程序因为unowed关键字而崩溃 - > weak在这里很有用。

as @kzaher says on github 正如@kzaher在github上所说

you should never use unowned. 你永远不应该使用无主。

sources: 来源:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM