Reputation: 10764
Subclassing from UITableViewController and I am getting two errors when trying to init
the TVC
class:
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
}
}
Error: Property self.vm not initialized at super.init call
The work around of making vm an optional (vm: ViewModel?) works, but I would like to it this way, if possible.
What am I doing wrong?
Upvotes: 0
Views: 791
Reputation: 123
Actually, you can change
let vm: ViewModel
to
var vm: ViewModel?
the error will not be showed.
Upvotes: 0
Reputation: 7361
There are workarounds, namely making the view model lazy (see Alesenka's solution) or an implicitly unwrapped optional (var vm: ViewModel!
) and initializing after self, but more important is figuring out your design pattern.
A view model shouldn't need to know about its controller; it just has the necessary information to populate the view, which the controller uses. Further, if you're actually holding on to the view controller after initializing the view model, they're both referencing each other, and you'll have a retain cycle. For these reasons, the best solution is to eliminate the need to pass in self
to the view model.
Upvotes: 1
Reputation: 1
You could make vm lazy
lazy var vm: ViewModel = {
return ViewModel(tvc: self)
}()
So you don't have to init this property in init method
Upvotes: 0