"对成员' init(...)"的模糊引用调用baseclass初始化器

时间:2016-08-26 12:41:43

标签: ios swift inheritance swift2 super

我有一个基类:

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()

我错过了什么和/或做错了什么?

3 个答案:

答案 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