popViewController выдает ошибку «освобожден, пока наблюдатели значения ключа еще зарегистрированы» - PullRequest
1 голос
/ 29 января 2020

У меня проблемы с удалением наблюдаемого, даже с использованием disposedBag. Это происходит только в iOS 10.

Мне нужно связать значение TextField (SwiftMaskField) с переменной в viewModel, поэтому я делаю:

class BaseViewController: UIViewController, Storyboarded {

    @IBOutlet weak var txtField: SwiftMaskField!

    var viewModel: BaseViewModel!

    override func viewDidLoad() {
        super.viewDidLoad()

        bindUI()
    }

    private func bindUI() {
        txtField.rx.text.orEmpty.bind(to: viewModel.myString).disposed(by: viewModel.bag)

        viewModel.showLoading.asObservable().skip(1).subscribe(onNext: { [unowned self] in
            self.showLoading()
        }).disposed(by: viewModel.bag)
    }

    ...
}

class BaseViewModel {
    var showLoading = BehaviorRelay<Void>(value: ())
    var myString = BehaviorRelay<String>(value:"")

    let bag = DisposeBag()

    func foo() {
        showLoading.accept(())
    }

    func foo2() {
        print(myString.value)
    }

    ...
}

Когда я делаю popViewController , мое приложение вылетает со следующей ошибкой:

*** Завершение работы приложения из-за необработанного исключения ' NSInternalInconsistencyException ', причина:' Экземпляр 0x7fbaafe45a20 класса SwiftMaskText.SwiftMaskField был освобожден, в то время как наблюдатели значения ключа все еще были зарегистрированы в нем. Информация о текущем наблюдении: (Контекст: 0x0, Свойство: 0x6000002596e0>) '


Это происходит только в iOS 10 (не тестировал предыдущие версии), дальнейшие версии не создаются sh.

Также я использую RxSwift 5.0.

1 Ответ

1 голос
/ 30 января 2020

Ваша сумка должна быть выше вашего взгляда в иерархии классов. Попробуйте это:

class BaseViewController: UIViewController, Storyboarded {

    private let bag = DisposeBag()

    @IBOutlet weak var txtField: SwiftMaskField!

    var viewModel: BaseViewModel!

    override func viewDidLoad() {
        super.viewDidLoad()

        bindUI()
    }

    private func bindUI() {
        txtField.rx.text.orEmpty.bind(to: viewModel.myString).disposed(by: bag)

        viewModel.showLoading.asObservable().skip(1).subscribe(onNext: { [unowned self] in
            self.showLoading()
        }).disposed(by: bag)
    }

    ...
}

Это, скорее всего, исправит это, дайте мне знать, если это не так.

Кроме того, вашей модели вида не нужна сумка для утилизации, если она вам нужна. там, вероятно, что-то не так.

...