斯威夫特3:初始化的UITableViewController自UITableViewController中

问题描述:

子类,我想initTVC类时得到两个错误:斯威夫特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?)的作品,但我希望如此,如果可能的话。

我在做什么错?

+0

你必须在调用.init之前初始化所有的let属性,但在我看来,你的想法是错误的:视图模型不应该知道视图,你应该使用一些观察者模式。 – cescobaz

有变通方法来初始化这个属性,也就是使视图模型懒(见Alesenka的解决方案)或隐式解包可选(var vm: ViewModel!)并自我初始化,但更重要的是弄清楚你的设计模式。

视图模型不需要知道其控制器;它只是具有必要的信息来填充控制器使用的视图。此外,如果在初始化视图模型后实际上持有视图控制器,则它们都是相互引用的,并且您将拥有retain cycle。出于这些原因,最好的解决方案是消除将self传递给视图模型的需要。

你可以让虚拟机lazy

lazy var vm: ViewModel = { 
    return ViewModel(tvc: self) 
}() 

所以你不必在init method

其实,你可以 变化

let vm: ViewModel 

var vm: ViewModel? 

错误将不会被显示。