【问题标题】:RxSwift: Is it safe to always use [unowned self] when a class has a disposeBag property?RxSwift:当类具有 disposeBag 属性时,始终使用 [unowned self] 是否安全?
【发布时间】:2017-10-20 07:19:31
【问题描述】:

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

假设我有一个 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
        }
    }
}

我应该能够简单地在订阅关闭时声明[unowned self],而不必担心我的应用程序会从self 变为nil 崩溃。

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

或者disposeBag 会先被释放而关闭不会完成?

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

【问题讨论】:

  • 我想你不能确定。这取决于内部实现和线程竞争。例如,如果 http 客户端捕获了您的闭包并调用了请求,那么即使 disposeBag 取消订阅,仍然可能存在竞争条件,并且 http 客户端可能会在处理 self 后立即调用您的闭包。

标签: ios swift rx-swift


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    你永远不应该使用 unowned。

    来源:

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

    【讨论】:

      猜你喜欢
      • 2012-02-20
      • 1970-01-01
      • 1970-01-01
      • 2015-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-02
      • 2021-11-03
      相关资源
      最近更新 更多