Это хорошая практика инициализации ViewController внутри метода подготовки к переходу? - PullRequest
0 голосов
/ 05 мая 2018

У меня есть 3 класса: MyProfileVC, NewProfileVC и NewProfileViewModel. Для облегчения написания тестов я решил создать инициализаторы в моих последних 2 классах, например:

NewProfileViewController:

var user: Users
var viewModel: NewProfileViewModel

init(for user: Users, with coreDataStack: CoreDataStack) {
    self.user = user
    self.viewModel = NewProfileViewModel(for: user, with: coreDataStack)

    super.init(nibName: nil, bundle: nil)
}

где NewProfileViewModel имеет свой собственный init:

var user: Users
var coreDataStack: CoreDataStack

init(for user: Users, with coreDataStack: CoreDataStack) {
    self.user = user
    self.coreDataStack = coreDataStack
}

И в конце я пытаюсь инициализировать их обоих как цепочку из MyProfileViewController как:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "toNewProfile" {
        var viewController = segue.destination as! NewProfileViewController
        viewController = NewProfileViewController(for: sender as? Users ?? Users(context: coreDataStack.mainContext), with: coreDataStack)            
    }
}

Так что это инициализирует мой NewProfileVC и NewProfileVC будет инициализировать NewProfileViewModel.

Но я хочу спросить разработчиков с более высоким опытом, чем у меня, является ли хорошей практикой инициализация VC внутри prepare: for segue таким образом, что я только что сделал, или вы можете дать мне лучшие идеи? Я не хочу писать код, который просто работает, но хочу построить хорошую архитектуру, и у меня нет ни одного наставника, чтобы спросить его об этом, поэтому единственное место - это стек, и я надеюсь, что вы мне поможете. Заранее спасибо!

1 Ответ

0 голосов
/ 05 мая 2018

Вы должны не инициализировать новый контроллер представления в prepareForSegue.

Назначение этого метода - от до настройка нового контроллера представления до его отображения . (выделение добавлено).

В результате вы получите инициализированный контроллер вида назначения. Важно использовать этот экземпляр, чтобы все выходы и действия, которые вы определили в раскадровке, были настроены правильно. Это не относится к контроллеру представления, инициализированному так, как вы показали.

Чтобы передать данные в контроллер представления, определите переменные данных как дополнительные в вашем NewProfileViewController:

var user: Users?
var viewModel: NewProfileViewModel?

и установите их в prepareForSegue:

if segue.identifier == "toNewProfile" {
    var viewController = segue.destination as! NewProfileViewController
    var user = Users ?? Users(context: coreDataStack.mainContext)
    viewController.user = user
    viewController.viewModel = NewProfileViewModel(for: user, with: coreDataStack)            
}

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

if segue.identifier == "toNewProfile" {
    var viewController = segue.destination as! NewProfileViewController
    var user = Users ?? Users(context: coreDataStack.mainContext)
    viewController.configureOnSegue(user: user, viewModel: NewProfileViewModel(for: user, with: coreDataStack))            
}

где добавленный метод контроллера вида будет выглядеть так:

func configureOnSegue(user: Users, viewModel: NewProfileViewModel) {
    self.user = user
    self.viewModel = viewModel
}
...