【问题标题】:UINavigationController subclass initializer with additional dependencies具有附加依赖项的 UINavigationController 子类初始化程序
【发布时间】:2018-06-16 11:53:57
【问题描述】:

我正在尝试创建一个 UINavigationController 的子类,它需要额外的依赖项。我还希望能够在初始化时创建和指定根视图控制器。我有这个代码:

init(rootVC: UIViewController, authUser: AppUser) {
    self.authUser = authUser
    super.init(rootViewController: rootVC)
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

但是,在尝试初始化时,我收到此错误:

致命错误:使用未实现的初始化程序“init(nibName:bundle:)” 上课

我查看了其他 SO 答案,特别是 this one,它建议通过覆盖 init(nibName:bundle:) 方法来解决问题。但是,这意味着我无法正确注入用户依赖项。如何最好地解决这个问题?

【问题讨论】:

  • 为什么不只是创建一个协议,定义您需要的依赖项并让您的自定义类符合它。
  • @RakshithNandish 这有什么帮助?我仍然需要以某种方式注入依赖项。简单地声明协议一致性不会进行任何注入。我只是声明该类将具有这些属性/功能。

标签: ios swift uikit subclass initializer


【解决方案1】:

你试过convenience初始化吗?

convenience init(rootVC: UIViewController, authUser: AppUser) {
    self.init(rootViewController: rootVC)
}

如果您要使用convenience 初始化,请同时阅读this question

编辑

你可以这样设置AppUser

final class Navigation: UINavigationController {

    private(set) var authUser: AppUser!

    convenience init(rootVC: UIViewController, authUser: AppUser) {
        self.init(rootViewController: rootVC)
        self.authUser = authUser
    }
}

编辑

关注this link

这是一种初始化接收器和推送的便捷方法 导航堆栈上的根视图控制器。每一次导航 stack 必须至少有一个视图控制器作为根。

【讨论】:

  • 我遇到的问题是 init(rootViewController:) 初始化程序不是从超类继承的。大概这是因为文档中的警告:“假设您为在子类中引入的任何新属性提供默认值,则适用以下两条规则。”由于我的依赖没有默认值,所以没有继承。如果我自己覆盖它,我会收到错误“无法分配给属性,authUser 是一个 let 常量”
  • @Cognitio 我认为它不是继承的,因为它不是指定的初始化程序。检查编辑的答案。
  • 它不是指定的初始化器吗?您可以从子类指定的初始化程序中调用它,如果它是便利初始化程序,您不应该这样做。您编辑的解决方案有效,但只能通过使依赖项成为可选(和变量)。我真的希望依赖项是一个常量并且不能设置为 nil,这使它更安全。
  • 另外,如果你继承了超类的所有指定初始化器,那么子类应该继承所有便利初始化器以及规则 2:“如果你的子类提供了它的所有超类指定初始化器的实现—*根据规则 1* 继承它们,或者通过提供自定义实现作为其定义的一部分—然后它会自动继承所有超类便利初始化程序。即使您的子类添加了更多便利初始化程序,这些规则也适用。”跨度>
  • @Cognitio 我只是给你一些信息来思考和解决方法,我不是一个伟大的专业人士。我又添加了一个编辑,说它是convenience 初始化
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-15
  • 2020-10-23
  • 2019-08-20
相关资源
最近更新 更多