I have a baseclass:
class ViewController: UIViewController
{
init(nibName nibNameOrNil: String?)
{
super.init(nibName: nibNameOrNil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) { }
}
a subclass:
class OneViewController: ViewController
{
private var one: One
init(one: One)
{
self.one = one
super.init(nibName: "OneNib")
}
required init?(coder aDecoder: NSCoder) { }
}
and a subclass of the above subclass:
class TwoViewController: OneViewController
{
private var two: Two
init(two: Two)
{
self.two = two
super.init(nibName: "TwoNib") <== ERROR
}
required init?(coder aDecoder: NSCoder) { }
}
At the indicated line I get the error:
Ambiguous reference to member 'init(one:)'
I don't understand why the compiler can't figure out I'm referring to ViewController
's init()
, like it managed to do in One
's init()
.
What am I missing and/or doing wrong?
I don't understand why the compiler can't figure out I'm referring to ViewController's
init()
, like it managed to do in One'sinit()
It is because, from inside TwoViewController, the compiler can't see ViewController's init
. The rule is:
As soon as you implement a designated initializer, you block inheritance of initializers.
Therefore, OneViewController has only one initializer, namely init(one:)
. Therefore, that is the only super
initializer that TwoViewController can call.
If you want ViewController's init(nibName:)
to be present in OneViewController, you must implement it in OneViewController (even if all it does is to call super
).
The chapter in the Swift manual on Designated Initializers will clarify it, but basically OneViewController
has only one way to set self.one
, and that's by initialising using init(one: One)
. You cannot bypass that, which is what you are trying to do.
If what you were trying to do could succeed, what value would two.one
have in the following?
let two = Two(two: SomeTwo)
print(two.one)
Answer - undefined. That's why it isn't allowed.
Having declared One.init(one:)
it is now the Designated Initializer, and there's no way to go round it.
you don't necessary pass value into constructor's ViewController . you can define public object in oneViewController and you access of outer .
class OneViewController: ViewController {
public var one: One
}
let vc = storyboard?.instantiateViewControllerWithIdentifier("OneViewController") as OneViewController
let one = One()
vc.one = one
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With