【问题标题】:Is it a good practice initialising ViewController inside of prepare for segue method?在 prepare for segue 方法中初始化 ViewController 是一个好习惯吗?
【发布时间】:2018-10-15 18:37:50
【问题描述】:

我有 3 个类:MyProfileVC、NewProfileVC 和 NewProfileViewModel。 为了使我的测试编写更容易,我决定在我的最后两个类中创建初始化器,如下所示:

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

但是我想问一下经验比我高的开发人员,以我刚刚所做的那样在prepare: for segue 中初始化VC 是否是一种好习惯,或者您可以给我更好的想法? 我不想编写简单有效的代码,而是想构建一个好的架构,我没有任何导师可以问他,所以唯一的地方是 Stack,我希望你能帮助我。 提前致谢!

【问题讨论】:

  • 不要使用init,使用configure(for:with:) 或类似的东西。因为segue.destination as! NewProfileViewController 应该已经是一个“init”(应该调用 initWithCoder:),因为它在 Storyboard 中。

标签: ios swift unit-testing mvvm architecture


【解决方案1】:

您应该prepareForSegue 中初始化新的视图控制器。

purpose of this method 用于在新视图控制器显示之前对其进行配置。 (强调)。

segue 为您提供了一个已初始化 目标视图控制器。使用此实例非常重要,这样您在情节提要中定义的所有出口和操作都正确设置。对于以您显示的方式初始化的视图控制器而言,情况并非如此。

要将数据传递给您的视图控制器,请将数据变量定义为 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
}

【讨论】:

  • 感谢您的回答!我只是想避免? 可选viewModel 变量在我的NewProfileVC 中。这就是为什么我尝试在 init 方法中初始化它们
  • 使用if let viewModel = self.viewModel { 是个好习惯吗?
  • 理想情况下,最好避免使用可选的 viewModel,但在这种情况下,您必须使用 if let 语法。另一种可能性是分配一个空的 viewModel 作为默认值。我已经使用了这两种方法,并且更喜欢使用可选的 viewModel。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-31
  • 2012-03-10
  • 2016-03-16
  • 1970-01-01
  • 2016-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多