斯威夫特3:初始化的UITableViewController自UITableViewController中
问题描述:
子类,我想init
的TVC
类时得到两个错误:斯威夫特3:初始化的UITableViewController自UITableViewController中
class TVC: UITableViewController {
let vm: ViewModel
override init(style: UITableViewStyle){
super.init(style: style)
self.vm = ViewModel(tvc: self) // Error: Property `self.vm` not initialized at super.init call
}
override init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!){
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
// Error: Property `self.vm` not initialized at super.init call
}
}
错误:Property self.vm not initialized at super.init call
工作围绕创建VM可选(VM的: ViewModel?)的作品,但我希望如此,如果可能的话。
我在做什么错?
答
有变通方法来初始化这个属性,也就是使视图模型懒(见Alesenka的解决方案)或隐式解包可选(var vm: ViewModel!
)并自我初始化,但更重要的是弄清楚你的设计模式。
视图模型不需要知道其控制器;它只是具有必要的信息来填充控制器使用的视图。此外,如果在初始化视图模型后实际上持有视图控制器,则它们都是相互引用的,并且您将拥有retain cycle。出于这些原因,最好的解决方案是消除将self
传递给视图模型的需要。
答
你可以让虚拟机lazy
lazy var vm: ViewModel = {
return ViewModel(tvc: self)
}()
所以你不必在init method
答
其实,你可以 变化
let vm: ViewModel
到
var vm: ViewModel?
错误将不会被显示。
你必须在调用.init之前初始化所有的let属性,但在我看来,你的想法是错误的:视图模型不应该知道视图,你应该使用一些观察者模式。 – cescobaz