我有一个基类:
class ViewController: UIViewController
{
init(nibName nibNameOrNil: String?)
{
super.init(nibName: nibNameOrNil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) { }
}
子类:
class OneViewController: ViewController
{
private var one: One
init(one: One)
{
self.one = one
super.init(nibName: "OneNib")
}
required init?(coder aDecoder: NSCoder) { }
}
和上述子类的子类:
class TwoViewController: OneViewController
{
private var two: Two
init(two: Two)
{
self.two = two
super.init(nibName: "TwoNib") <== ERROR
}
required init?(coder aDecoder: NSCoder) { }
}
在指定的行我得到错误:
Ambiguous reference to member 'init(one:)'
我不明白为什么编译器无法理解我引用的ViewController
init()
,就像它在One
设法做的那样{1}} init()
。
我错过了什么和/或做错了什么?
答案 0 :(得分:8)
我不明白为什么编译器无法弄清楚我指的是ViewController的
中设法做的那样init()
,就像它在One的init()
这是因为,从TwoViewController内部,编译器无法看到 ViewController的init
。规则是:
只要您实施指定的初始化程序,就会阻止初始化程序的继承。
因此,OneViewController只有一个初始值设定项,即init(one:)
。因此,这是TwoViewController可以调用的唯一super
初始值设定项。
如果你希望ViewController的init(nibName:)
出现在OneViewController中,你必须在OneViewController中实现它(即使它只是调用super
)。
答案 1 :(得分:3)
关于Designated Initializers的Swift手册中的章节将澄清它,但基本上OneViewController
只有一种设置self.one
的方法,并且使用{{1}进行初始化}}。你不能绕过那个,这是你想要做的。
如果您尝试做的 可以成功,init(one: One)
下面会有什么价值?
two.one
答案 - 未定义。这就是为什么它不被允许的原因。
宣布let two = Two(two: SomeTwo)
print(two.one)
后,它现在是指定初始化程序,并且没有办法绕过它。
答案 2 :(得分:1)
您没有必要将值传递给构造函数的ViewController。你可以在oneViewController中定义公共对象,然后访问外部。
class OneViewController: ViewController {
public var one: One
}
let vc = storyboard?.instantiateViewControllerWithIdentifier("OneViewController") as OneViewController
let one = One()
vc.one = one