I have the following 2 classes and a protocol: WeatherFacade and WeatherObject, which is of type of the protocol ModelObjects (WeatherObject conforms to ModelObjects and is type ModelObjects). I want to create an instance of the WeatherObject by it's name but I get error:
'init' is a member of the type; use 'type(of: ...)' to initialize a new object of the same dynamic type
The WeatherFacade class consists of a Networking Class and a WeatherObject properties and init like so:
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 looks like this
protocol ModelProtocol{
func parse<T: Decodable>(data: Data) throws -> Array<T>?
}
WeatherObject is nothing at this point, just a classname that conforms to ModelProtocol like so:
class WeatherModel: NSObject, ModelProtocol {}
The class in question uses the standard init()
. How can I get an instance of my WeatherObject by passing in the name?
This line:
class WeatherModel: NSObject, ModelProtocol {}
causes error. You should better try to show enough code to reproduce your issue.
Anyway, you have two major problems.
First, this declaration let className: ModelProtocol
declares className
as an instance conforming to the protocol ModelProtocol
. It's not the declaration for a type.
Second, there is no default initializer in Swift. When you want to call init()
on a type variable conforming to a protocol, the protocol needs to declare init()
.
So, your protocol should be something like this:
protocol ModelProtocol{
func parse<T: Decodable>(data: Data) throws -> Array<T>?
init()
}
You need to add required
initializer to conform to it:
class WeatherModel: NSObject, ModelProtocol {
func parse<T: Decodable>(data: Data) throws -> Array<T>? {
//...
return [/*...*/]
}
override required init() {
super.init()
}
}
And then, you can write something like this:
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()
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.