【发布时间】:2017-10-26 14:49:24
【问题描述】:
尝试重构我的代码以避免必须在各处引用共享实例,而是我想通过自定义初始化程序注入它们。我对 Swift 初始化的有限理解阻止了我这样做。
这是我的 ViewController,减去方法和样板:
class LoginVC: UIViewController {
let dataManager: DataManager
let restManager: RestManager
let defaults: UserDefaults
init(defaults: UserDefaults = .standard, dataManager: DataManager = .sharedInstance, restManager: RestManager = .sharedInstance) {
self.defaults = defaults
self.dataManager = dataManager
self.restManager = restManager
super.init(nibName: nil, bundle: nil)
}
}
我已经提供了默认值,这些默认值是在各自的 DataManager 和 RestManager 单例类中声明为静态常量的共享实例。计划在每个引用了这些单例的 ViewController 中执行此操作。无论如何,当编译器抱怨我必须提供所需的初始化程序 init(coder: aDecoder) 时,我的问题就出现了。
没问题,但是实施后……
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
...编译器再次抱怨,这一次
Blockquote 属性“self.defaults”未在 super.init 调用时初始化
我想这是有道理的,因为需要初始化?据我所知,是一个委托初始化(可能是我在这里完全弄错了)。我不知道如何将自定义 init 的默认参数传递给此初始化程序的超级 init,或者是否有可能。
我尝试了一种解决方法,方法是将常量更改为可变变量,并像这样将它们隐式展开:
class LoginVC: UIViewController {
var dataManager: DataManager!
var restManager: RestManager!
var defaults: UserDefaults!
init(defaults: UserDefaults = .standard, dataManager: DataManager = .sharedInstance, restManager: RestManager = .sharedInstance) {
self.defaults = defaults
self.dataManager = dataManager
self.restManager = restManager
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
这种解决方法实际上可以编译和构建,但是一旦 viewDidLoad 中的 userDefaults 被解包,应用程序就会崩溃,因为它们有一个 nil 值。尽管它们在自定义初始化程序的参数中被默认为默认值,但它们都具有 nil 值,这让我相信我已经彻底搞砸了。
任何帮助/澄清将不胜感激,在此先感谢。
【问题讨论】:
标签: swift dependency-injection uiviewcontroller initialization singleton