Я работаю над проектом iOS с RxSwift, и я использую MVVM с шаблоном координаторов.
Вот моя реализация:
ViewModel:
// MARK: - Private
private let showNextViewSubject = PublishSubject<Void>()
// MARK: - Inputs
var showNextView: AnyObserver<Void> {
return showNextViewSubject.asObserver()
}
// MARK: - Outputs
var didShowNextView: Observable<Void> {
return showNextViewSubject.asObservable()
}
ViewController:
private func bindButton() {
_ = button.rx.tap
.bind(to: viewModel.showNextView)
.disposed(by: disposeBag)
}
Координатор:
self.viewModel.didShowNextView
.subscribe(onNext: { [weak self] _ in
self?.showNextView()
})
.disposed(by: disposeBag)
Моя проблема связана с [weak self] _ в координаторе: когда я добавляю его, self?.showNextView() никогда не вызывается, но это хорошо работает, когда я его удаляю.
Ты знаешь почему?
Спасибо, Ромен





Если вы не добавите [weak self], блок завершения сохранит self, и это не лучший способ использовать блоки. У вас должна быть ссылка (сохранена) на вашего координатора, и ее следует выпустить, когда вы закончите с ней.
Когда вы избавляетесь от [weak self], блок создает сильную ссылку на self, так что он не освобождается, когда любой другой код выполняется с его использованием. Сделав ссылку слабой, self может быть освобожден, что, вероятно, и происходит. Это означает, что нет другого объекта с сильной ссылкой на self, поэтому он равен нулю и вызов не будет выполнен. Избавление от него может создать цикл сохранения, поэтому вы должны быть осторожны с этим.
Похоже, у вас есть другие проблемы с зависимостями.
Если он не выполняется, это, вероятно, связано с тем, что ваш координатор освобожден до срабатывания события. Я полагаю, что здесь нет четкой ссылки на вашего предыдущего координатора. Вы можете проверить это, добавив print(...) в deinit.
В Swift 4.2 вы можете спокойно переписать фрагмент как:
self.viewModel.didShowNextView
.subscribe(onNext: { [weak self] in
guard let self = self else { return }
self.showNextView()
})
.disposed(by: disposeBag)
Этот шаблон обычно рекомендуется использовать вместо self?.
Нет разницы между кодом, который вы написали выше, и просто использованием self?.
просто держите ссылку на этого координатора в его родительском координаторе вот так
private var childCoordinators = [CoordinatorType]()
так что он не будет освобожден
Да, ты прав. Однако я не понимаю, почему, но я попытался добавить печать в свое закрытие, чтобы прослушать подписку: с
[weak self] _ничего не происходит, а без него все работает ...