当以编程方式推送视图控制器时,可以很容易地通过init方法进行一些依赖注入:
let dummyVC = DummyVC(dummyManager: DummyManager())
self.pushViewController(dummyVC, animated: true)使用目标控制器:
class DummyVC: UIViewController {
private let dummyManager: DummyManager
init(dummyManager: DummyManager) {
self.dummyManager = dummyManager
super.init(nibName: nil, bundle: nil)
}
}前面的代码很好,因为它正确地封装了属性,并清楚地显示了对外部API的依赖关系。
当使用故事板时,我们不能选择被调用的init方法(正在调用一个自定义的init方法)。
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let dummyVC = mainStoryboard.instantiateViewControllerWithIdentifier("DummyVC") as! DummyVC
dummyVC.dummyManager = DummyManager() // ERROR: would require dummyManager to have public scope有没有办法在保持属性私有和常量(let)的同时以同样的方式注入依赖关系?
发布于 2018-08-23 22:31:34
序列图像板中的视图控制器始终使用
init?(coder aDecoder: NSCoder)这是没有办法的。
另一种方法是使用…
class DummyVC: UIViewController {
private var dummyManager: DummyManager!
func configure(dummyManager: DummyManager) {
self.dummyManager = dummyManager
}
}然后是…
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let dummyVC = mainStoryboard.instantiateViewControllerWithIdentifier("DummyVC") as! DummyVC
dummyVC.configure(dummyManager: DummyManager())或
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.destination {
case let dummyVC as DummyVC:
dummyVC.configure(dummyManager: DummyManager())
default:
break
}
}虽然不完美(使用let而不是var),属性为private和隐式展开的可选意味着必须设置它(否则应用程序在使用时会崩溃),而这只能在包含类的内部发生。
我已经在我的应用程序中采用了这个方法,并且发现它是确保所有属性都被设置的一个很好的方法。只要记住当一个属性被添加到一个类中时更新configure函数即可。
https://stackoverflow.com/questions/51988061
复制相似问题