为什么视图控制器的 deinit 不使用 RXSwift 调用?
why deinit of view controller is not calling using RXSwift?
我尝试了一些方法,但找不到解决方案。我正在 onNext 块中导航控制器,但 deinit 没有调用。我还在 rx 闭包中声明了 self 是弱的。
下面是完整的class代码。
如有错误请指正:
class LoginVC: UIViewController {
//MARK:- Variables & Consts
private let tag = "LoginVC"
private let loginViewModel = LoginViewModel()
private let disposeBag = DisposeBag()
//MARK:- IBOutlets
@IBOutlet weak var tfUsername: MFTextField!
@IBOutlet weak var tfPassword: MFTextField!
@IBOutlet weak var btnLogin: UIButton!
//MARK:- View Controller Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
setupBindings()
}
///deinit
deinit {
print(" deinit")
}
//MARK:- Custom Methods
private func setupBindings() {
loginViewModel
.loginResponse
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [weak self] loginResponse in
let vc = UIStoryboard(name: Constants.MAIN, bundle: nil).instantiateViewController(withIdentifier: Constants.HOME_VC)
self?.navigationController?.pushViewController(vc, animated: true)
}, onError: { [weak self] error in
self?.removeLoader()
}, onCompleted: { [weak self] in
self?.removeLoader()
}, onDisposed: { [weak self] in
print("\(self?.tag ?? "") onDisposed")
})
.disposed(by: disposeBag)
btnLogin.rx.tap.bind{ [weak self] in
self?.loginViewModel.login(username: self?.tfUsername.text ?? "", password: self?.tfPassword.text ?? "")
}.disposed(by: disposeBag)
}
}
如有任何帮助,我们将不胜感激。
您在您的可观察链中强烈捕获 self
。然后将保存订阅的一次性物品放入一个 属性 of self
.
的 disposeBag 中
这意味着你有一个引用循环。您的视图控制器已捕获自身。
您正在将下一个视图控制器推送到此处。
self?.navigationController?.pushViewController
执行此操作时,LoginVC
永远不会被释放,因为它仍在内存和导航控制器的堆栈中。所以没有理由调用deinit
。
deinit
只有在您关闭 LoginVC
时才会被调用。如果你的 LoginVC
是你的根 viewcontroller,它永远不会称它为 deinit
。
这与 RxSwift 无关。
我尝试了一些方法,但找不到解决方案。我正在 onNext 块中导航控制器,但 deinit 没有调用。我还在 rx 闭包中声明了 self 是弱的。
下面是完整的class代码。 如有错误请指正:
class LoginVC: UIViewController {
//MARK:- Variables & Consts
private let tag = "LoginVC"
private let loginViewModel = LoginViewModel()
private let disposeBag = DisposeBag()
//MARK:- IBOutlets
@IBOutlet weak var tfUsername: MFTextField!
@IBOutlet weak var tfPassword: MFTextField!
@IBOutlet weak var btnLogin: UIButton!
//MARK:- View Controller Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
setupBindings()
}
///deinit
deinit {
print(" deinit")
}
//MARK:- Custom Methods
private func setupBindings() {
loginViewModel
.loginResponse
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [weak self] loginResponse in
let vc = UIStoryboard(name: Constants.MAIN, bundle: nil).instantiateViewController(withIdentifier: Constants.HOME_VC)
self?.navigationController?.pushViewController(vc, animated: true)
}, onError: { [weak self] error in
self?.removeLoader()
}, onCompleted: { [weak self] in
self?.removeLoader()
}, onDisposed: { [weak self] in
print("\(self?.tag ?? "") onDisposed")
})
.disposed(by: disposeBag)
btnLogin.rx.tap.bind{ [weak self] in
self?.loginViewModel.login(username: self?.tfUsername.text ?? "", password: self?.tfPassword.text ?? "")
}.disposed(by: disposeBag)
}
}
如有任何帮助,我们将不胜感激。
您在您的可观察链中强烈捕获 self
。然后将保存订阅的一次性物品放入一个 属性 of self
.
这意味着你有一个引用循环。您的视图控制器已捕获自身。
您正在将下一个视图控制器推送到此处。
self?.navigationController?.pushViewController
执行此操作时,LoginVC
永远不会被释放,因为它仍在内存和导航控制器的堆栈中。所以没有理由调用deinit
。
deinit
只有在您关闭 LoginVC
时才会被调用。如果你的 LoginVC
是你的根 viewcontroller,它永远不会称它为 deinit
。
这与 RxSwift 无关。