RxSwift:当类具有 disposeBag 属性时,始终使用 [unowned self] 是不是安全?
Posted
技术标签:
【中文标题】RxSwift:当类具有 disposeBag 属性时,始终使用 [unowned self] 是不是安全?【英文标题】: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 后立即调用您的闭包。 【参考方案1】:根据我的经验,将 unowned
与处置袋一起使用是一种安全的方法,除了一个块 - onDisposed
。有一些应用程序因为 unowed
关键字而崩溃的情况 -> weak
在这里很有用。
【讨论】:
【参考方案2】:正如@kzaher 在 github 上所说的那样
你永远不应该使用 unowned。
来源:
https://github.com/RxSwiftCommunity/RxDataSources/issues/169 https://github.com/ReactiveX/RxSwift/issues/1593
【讨论】:
以上是关于RxSwift:当类具有 disposeBag 属性时,始终使用 [unowned self] 是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章
RxSwift:disposed(by: disposeBag) 真的有效吗?
ViewController 中的 RxSwift DisposeBag 使用