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

时间:2017-10-20 07:19:31

标签: ios swift rx-swift

我最近发现一篇文章说,只要您将订阅添加到[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是否会先解除分配,闭包不会完成?

关于如何知道一个类是否拥有一个闭包的任何澄清都会很棒。

2 个答案:

答案 0 :(得分:0)

根据我的经验,除了一个区块unowned之外,使用onDisposed和一个废弃袋是一种安全的方法。有些应用因unowed关键字而导致应用崩溃的情况 - > weak在这里很有用。

答案 1 :(得分:0)

正如@kzaher在github上所说的

  

你永远不应该使用无主。

来源:

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