通过类名称的Swift初始化程序会导致错误:类的类型为“协议”

时间:2018-09-14 03:05:28

标签: swift

我有以下2个类和一个协议:WeatherFacade和WeatherObject,其类型为协议ModelObjects(WeatherObject符合ModelObjects,类型为ModelObjects)。我想通过它的名称创建WeatherObject的实例,但出现错误:

  

'init'是该类型的成员;使用'type(of:...)'初始化具有相同动态类型的新对象

WeatherFacade类由网络类和WeatherObject属性组成,其初始化方式如下:

let networking: Networking
let model: ModelProtocol

init(model: String) {
    self.networking = Networking()


    let namespace = Bundle.main.infoDictionary!["CFBundleExecutable"] as! String

    let className: ModelProtocol = NSClassFromString("\(namespace).\(model)") as! ModelProtocol

    self.model = className.init()//error here
}

ModelProtocol看起来像这样

protocol ModelProtocol{

    func parse<T: Decodable>(data: Data) throws -> Array<T>?

}

此时的WeatherObject还算不上什么,只是一个符合ModelProtocol的类名,如下所示:

class WeatherModel: NSObject, ModelProtocol {}

所讨论的类使用标准init()。如何通过传入名称获取WeatherObject的实例?

1 个答案:

答案 0 :(得分:1)

此行:

class WeatherModel: NSObject, ModelProtocol {}

导致错误。您最好尝试显示足够的代码来重现您的问题。


无论如何,您有两个主要问题。

首先,此声明let className: ModelProtocol声明className为符合协议ModelProtocol的实例。这不是类型的声明。

第二,Swift中没有默认的初始化程序。要在符合协议的类型变量上调用init()时,协议需要声明init()

因此,您的协议应该是这样的:

protocol ModelProtocol{

    func parse<T: Decodable>(data: Data) throws -> Array<T>?

    init()

}

您需要添加required初始化程序以使其符合以下条件:

class WeatherModel: NSObject, ModelProtocol {

    func parse<T: Decodable>(data: Data) throws -> Array<T>? {
        //...
        return [/*...*/]
    }

    override required init() {
        super.init()
    }
}

然后,您可以编写如下内容:

init(model: String) {
    self.networking = Networking()

    let namespace = Bundle.main.infoDictionary!["CFBundleExecutable"] as! String

    let classType: ModelProtocol.Type = NSClassFromString("\(namespace).\(model)") as! ModelProtocol.Type

    self.model = classType.init()
}