Ссылка на Observable с инъекцией класса - PullRequest
0 голосов
/ 07 июня 2018

Пожалуйста, рассмотрите следующую структуру:

class UpModel {
    var isThisRealLife: Variable<Bool>

    required init(model: UpperModel) {
        isThisRealLife = Variable(upperModel.isThisRealLife) //true
        testFlagChange()
    }

    private func testFlagChange() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
            self.isThisRealLife = false
        }
    }
}

Эта модель создается UpperViewModel путем внедрения собственного UpperModel экземпляра, что-то вроде этого:

class UpperViewModel {
    init() {
        let upperModel = UpperModel()

        let upModel = UpModel(model: upperModel)
        let upViewModel = UpViewModel(model: upModel)
    }
}

Теперь у меня есть UpViewModel класс:

class UpViewModel {
    let bag = DisposeBag()

    init(model: UpModel) {
        let upModelVariable = Variable(model)
        let lowViewModel = LowViewModel<LowModel>(model: upModelVariable)

        upModelVariable.asObservable().flatMap({ $0.isThisRealLife.asObservable() }).subscribe(onNext: { value in
            print("changed to \(value) -- at UpVM") //1
        }).disposed(by: bag)
    }
}

1: правильно реагирует на изменение флага через 3 секунды.

Хорошо, пока все хорошо.Но теперь я хочу продолжать отправлять эту ссылку UpClass вниз, чтобы другие классы могли реагировать на изменения свойства isThisRealLife.

Так что это мой LowViewModel, который получает ссылку UpModel:

class LowViewModel<Model: LowModel> {
    let bag = DisposeBag()
    let lowModel: LowModel

    required init(model: Variable<UpModel>) {
        lowModel = Model(model: model.value) 

        model.asObservable().flatMap({ $0.isThisRealLife.asObservable() }).subscribe(onNext: { value in
            print("changed to \(value) -- at LowVM") //2
        }).disposed(by: bag)
    }
}

2: Это не реагирует на изменение флага.

И это LowModel, но я даже пока не использую его, так какКажется, я теряю ссылку на свойство isThisRealLife на предыдущем шаге:

class LowModel {
    var isThisRealLife: Observable<Bool>

    required init(model: UpModel) {
        isThisRealLife = model.isThisRealLife.asObservable
    }
}

Примечания :

  • Я понимаю, Variable устарела иЯ сделаю рефакторинг на BehaviorRelay, как только смогу заставить все работать.
  • Я попытался сделать пример как можно меньше, чтобы проиллюстрировать проблему, но, конечно, проблема может быть в более широком контексте -в этом случае я с радостью предоставлю больше информации по мере необходимости.
  • Существует множество протоколов, используемых для придания универсальности и возможности повторного использования, поэтому я удалил все из них, чтобы попытаться сосредоточиться (по крайней мере, на мой взгляд)проблема.Кроме того, графический интерфейс не важен сейчас, только бизнес-логика.

Несколько более длинный контекст на случай, если кому-то интересно:

Я и моя команда работаем над новымархитектура для нашего проекта.Поскольку наш дизайн довольно последовательный, мы проверяем эту концепцию работы с «компонентами», которые представляют собой набор View, ViewModel и Model, которые можно повторно использовать в приложении.

Основная идея заключается в том, что каждыйscreen представляет собой набор MVVM с ViewController, ViewModel и Model, и они реализуют «компоненты» по мере необходимости.Мы внедряем Reactive, чтобы позволить некоторым компонентам реагировать при определенных изменениях в «родительской» / «верхней» модели.

Я работаю с реактивным в RxSwift уже почти год, ноПроект, над которым я работал, был довольно простым, и его использование было повторяющимся, поэтому мои знания по этому вопросу стали узкими (что было моей ошибкой, ofc).

Спасибо за любую помощь.

1 Ответ

0 голосов
/ 08 июня 2018

Я думаю, вы запутались с передачей по значению или ссылкой на init.

Я не уверен, какова ваша цель этого дизайна .. Я не мог правильно понять, но я думаю, что ваша проблема ...

в # 1 вы создали новую локальную переменную
let upModelVariable = Variable (model)

в 2 # вы зарегистрировали параметр func как наблюдаемый, но он умирает при возврате init, потому что он передается по значению (try inout)

Вот почему# 1 работает, а # 2 - нет.

Попробуйте использовать inout для передачи ссылки следующим образом [посмотрите, работает ли она так, как вы хотели]

    init(model: UpModel) {
            var upModelVariable = Variable(model)
            let _ = LowViewModel<LowModel>(model: &upModelVariable)

            upModelVariable.asObservable().flatMap({ $0.isThisRealLife.asObservable() }).subscribe(onNext: { value in
                print("changed to \(value) -- at UpVM") //1
            }).disposed(by: bag)
        } 
class LowViewModel<Model: LowModel> {
    let bag = DisposeBag()
    let lowModel: LowModel
    required init( model: inout Variable<UpModel>) {
        lowModel = Model(model: model.value)

        model.asObservable().flatMap({ $0.isThisRealLife.asObservable() }).subscribe(onNext: { value in
            print("changed to \(value) -- at LowVM") //2
        }).disposed(by: bag)
    }
}
...