【问题标题】:why deinit of view controller is not calling using RXSwift?为什么视图控制器的 deinit 不使用 RXSwift 调用?
【发布时间】:2021-02-25 09:16:17
【问题描述】:

我尝试了一些方法,但找不到解决方案。我在 onNext 块中导航控制器,但 deinit 没有调用。我还在 rx 闭包中声明了 self 是弱的。

下面是完整的类代码。 如果我做错了什么请纠正:

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)
    }
}

任何帮助将不胜感激。

【问题讨论】:

  • @bseh 您提供的链接完全不相关 感谢您分享想法。
  • 您分享的代码中没有视图控制器。
  • 您希望何时调用它?您是否正确关闭了此视图控制器?
  • @RukshanMarapana 我已经更新了代码,请检查我将其导航到下一个控制器的 .subscribe 块,结果仍然相同。

标签: ios swift reactive-programming rx-swift rx-cocoa


【解决方案1】:

你在这里推送下一个视图控制器。

self?.navigationController?.pushViewController

当您这样做时,LoginVC 永远不会被释放,因为它仍在内存和导航控制器的堆栈中。所以没有理由调用deinit

deinit 只会在您关闭 LoginVC 时被调用。如果你的LoginVC 是你的根视图控制器,它永远不会称它为deinit。 这与 RxSwift 无关。

【讨论】:

  • 谢谢,@Rukshan Marapana 我的问题与此类似,现在已解决:)
【解决方案2】:

您在可观察链中强烈捕获self。然后将保存订阅的一次性物品放入作为self 属性的 disposeBag 中。

这意味着你有一个参考周期。您的视图控制器已自行捕获。

【讨论】:

  • 我在我们的可观察链中声明为[弱自我]。我还需要做什么来解决这个问题?
  • 你没有在上面代码的每个地方都声明为[weak self]。如果您更改了代码但仍有问题,请编辑问题中的代码。
  • @Ale 更具体地说,您的 onCompleted 在您上面发布的代码中没有 [weak self]。
  • @DanielT。我已经尝试了您要求的更改并更新了上述代码补丁,但结果仍然相同。它不工作。
  • 请发布整个课程。您未发布的代码中可能存在一个保留周期。
猜你喜欢
  • 2016-07-05
  • 2017-01-18
  • 2017-10-06
  • 2019-08-08
  • 1970-01-01
  • 2016-03-22
  • 2021-05-16
  • 1970-01-01
  • 2018-05-24
相关资源
最近更新 更多