user12345 user12345 -5 years ago 181
iOS Question

When to initialise viewController global variables using swift

I come from an Objective C background and I'm normally used to declaring my properties (global variables to the class) inside the init method of a given class i.e. something like this:

-(instancetype) init {
self = [super init];
if(self){
self.viewModel = [[MyViewModel alloc] init:self];
}
return self;
}


When self.viewModel is a property and I normally pass the a view controller as a parameter to the view model for callback purposes. I'm currently trying to do the same in swift.

I have a normal a custom view controller class, with the following init method:

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nil, bundle: nil)
self.viewModel = SearchViewModel(callback: self)
}


Now with the code above, xcode complains that


self.viewModel has not been initialised


However when I try initialise the viewModel i.e:

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
self.viewModel = SearchViewModel(callback: self)
super.init(nibName: nil, bundle: nil)
}


I then get


self used before super.init call


How would I sort this out in Swift?

Answer Source

First off: Swift initializers want all properties of self to be set up properly / to have a value before calling a super initializer.

Second off: You mustn't use self before the super.init-call because otherwise the properties that you would set in the super constructor are not yet set meaning whoever receives the non-finished self-instance can not be sure about the state of self.

Solution: Make viewModel of type SearchViewModel! and use the first code alternative.

Explanation: By making viewModel an implicitly unwrapped optional it implicitly contains nil in the beginning, therefore you can now call super.init and set an actual value to viewModel after that.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download