Reputation: 335
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.
Assuming I have a ViewController where deinit
is not being called due to a strong reference:
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
.
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?
Or would the disposeBag
be deallocated first and the closure wouldn't complete?
Any clarification about how to know whether or not a class owns a closure would be great too.
Upvotes: 4
Views: 2540
Reputation: 432
as @kzaher says on github
you should never use unowned.
sources:
https://github.com/RxSwiftCommunity/RxDataSources/issues/169 https://github.com/ReactiveX/RxSwift/issues/1593
Upvotes: 0
Reputation: 2259
In my experience it's a safe approach to use unowned
with a dispose bag, except one block - onDisposed
. There have been the cases when an app crashed because of unowed
keyword -> weak
is useful here.
Upvotes: 1