Быстрый инициализатор по имени класса вызывает ошибку: класс имеет тип «Протокол» - PullRequest
0 голосов
/ 14 сентября 2018

У меня есть следующие 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 голосов
/ 14 сентября 2018

Эта строка:

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()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...