【问题标题】:non-nominal type X does not support explicit initialization非标称类型 X 不支持显式初始化
【发布时间】:2017-09-27 23:22:19
【问题描述】:

我试图理解我在 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 方法还不够吗?

【问题讨论】:

    标签: ios swift xcode generics swift4


    【解决方案1】:

    您只需要在初始化泛型参数而不是“真实”类型时显式使用init

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

    【讨论】:

    • 谢谢,比我得到No 'C.Type.init' candidates produce the expected contextual result type '_?'
    • 它在 Swift 4.1 中不起作用。我必须删除 UIViewController 约束。但我需要这个约束。知道如何解决吗?
    • 在初始化定义之前添加所需的语句,这样就可以了
    【解决方案2】:

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

    【讨论】:

    • 谢谢,比我得到No 'C.Type.init' candidates produce the expected contextual result type '_?'
    • 在我的主要项目中,这实际上解决了这个问题。但是检查另一个答案,因为它是第一个。再次感谢!
    【解决方案3】:

    请检查:

    在您的代码中,您正在这样做C : MainViewControllerInterface, C : UIViewController

    它将C视为ViewController,然后在ViewController中没有initinit(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()
        }
    }
    

    【讨论】:

    • 谢谢,但 C 是 C : MainViewControllerInterface。该协议定义了我在那里使用的初始化程序。
    • 删除 ViewController 后,它的工作。请检查我的代码。
    • 是的,但是,这就像我需要的东西。你说It is treating C as ViewController, then there is no init in ViewController like init(modelView: M) thats why its throwing error 但这对我来说没有意义。 C也是采用MainViewControllerInterface,为什么编译器还不够呢?
    • 是因为 UIViewController 是一个类而不是一个协议吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多