非标称类型X不支持显式初始化

时间:2017-09-27 23:22:19

标签: ios swift xcode generics swift4

我正试图了解我在swift中对泛型做错了什么。

我创建了这个示例游乐场

import UIKit

public protocol MainControllerToModelInterface : class {
    func addGoal()
    init()
}

public protocol MainViewControllerInterface : class {
    associatedtype MODELVIEW
    var modelView: MODELVIEW? {get set}

    init(modelView: MODELVIEW)
}

public class MainViewController<M> : UIViewController, MainViewControllerInterface where M : MainControllerToModelInterface {
    public weak var modelView: M?

    required public init(modelView: M) {
        self.modelView = modelView
        super.init(nibName: String(describing: MainViewController.self), bundle: Bundle.main)
    }

    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

public class Other<C, M> : NSObject where C : MainViewControllerInterface, C : UIViewController, M : MainControllerToModelInterface, C.MODELVIEW == M {
    var c : C?

    override init() {
        let m = M()
        self.c = C(modelView: m)
        super.init()
    }
}

self.c = C(modelView: m)行给了我这个错误non-nominal type 'C' does not support explicit initialization

this other stack overflow问题我发现旧Xcode版本中的此错误意味着

cannot invoke initializer for type '%type' with an argument list of type '...' expected an argument list of type '...'

但是在操场上方,编译器缺少什么?

我在使用swift4 / xcode9。

更新

在遵循建议Use C.init(modelView: m) rather than C(modelView: m)之后,错误发生了变化:

No 'C.Type.init' candidates produce the expected contextual result type '_?'

比@ vini-app建议删除UIViewController以使其正常工作。我仍然不明白为什么当UIViewController存在时编译器不满意。知道C有那种有效的init方法还不够吗?

3 个答案:

答案 0 :(得分:33)

您只需在初始化通用参数而非“真实”类型时明确使用init

self.c = C.init(modelView: m)

答案 1 :(得分:2)

使用C.init(modelView: m)而不是C(modelView: m)。那应该解决它。

答案 2 :(得分:1)

请检查:

在您的代码中,您正在执行此操作C : MainViewControllerInterface, C : UIViewController

C视为ViewController,ViewController中没有init,如init(modelView: M),这就是为什么抛出错误

public class Other<C, M> : NSObject where C : MainViewControllerInterface, M : MainControllerToModelInterface, C.MODELVIEW == M {
    var c : C?

    override init() {
        let m = M()
        self.c = C(modelView: m)
        super.init()
    }
}