Reputation: 24912
I'm trying to add simple initialiser to a UIViewController
in Swift
. So far it has been very frustrating...
First I tried adding it as a convenience init:
class ImageViewController: UIViewController {
var model: UIImage
convenience init(model: UIImage){
self.init(nibName: nil, bundle: nil)
self.model = model
}
....
If I do this, the compiler forces me to implement required init(coder aDecoder: NSCoder)
. I checked the definition of the UIViewController
class and there's no such requirement, but anyway.
To make things worse, the compiler complains that the self.init(nibName: nil, bundle: nil)
call has an erroneous extra argument in bundle:
. Again, I checked the class definition and the initialiser signature requires both parameters.
So I decided to make it a designated init. It's not what I want, as I don't want to lose all the superclass initialisers.
Now it seems to be happy with the self.init(nibName: nil, bundle: nil)
call, but it still insists that I implement init(coder aDecoder: NSCoder)
.
Any ideas of what's going on? I can't make head or tails of this...
Upvotes: 2
Views: 862
Reputation: 126377
If you don't want the model
property to be optional, don't make it optional. Sure, it's a bitch to have to implement initWithCoder:
, but it's better to have rock-solid, secure code.
class ImageViewController: UIViewController {
var model: UIImage
init(model: UIImage) {
self.model = model
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
This ensures that the only way an instance of ImageViewController
can be created is by calling initWithModel:
and therefore guarantees that model
will always have a nonoptional value.
Maybe in the future, Apple will add a convenient way of doing this, but for now, I must sacrifice convenience for control.
Upvotes: 1
Reputation: 539805
The error messages are indeed confusing, but I think they come from the fact that
if the model
property has no default value then the required initializers are no longer
inherited from the superclass. With an optional (or implicitly unwrapped optional) property
(which has the default value nil
) your code compiles:
class ImageViewController: UIViewController {
var model: UIImage!
convenience init(model: UIImage) {
self.init(nibName: nil, bundle: nil)
self.model = model
}
}
Upvotes: 3