Невозможно вызвать метод со списком аргументов универсального типа - PullRequest
0 голосов
/ 20 декабря 2018

У меня есть ListDataSource, который управляет всеми списками моделей ListDataModel ниже:

protocol Serializable {} // Empty protocol

protocol AncestorListDataModel {}

protocol ListDataModel: AncestorListDataModel {
  associatedtype T: Serializable
  var items: [T] { get }
}

class BaseListDataModel<T>: ListDataModel where T: Serializable {
  ...
}

class BaseListDataSource: NSObject {
  private var listModels: [String: AncestorListDataModel] = [:]
  private(set) var modelMapping: [String: Serializable.Type] = [:]
  ...

  func getModel<T>(of type: T.Type, at index: Int) -> T? where T: Serializable {
    if let models = self.listModels[String(describing: T.self)] as? BaseListDataModel<T> {
        if index < 0 && index >= models.items.count {
            return nil
        }

        return models.items[index]
    }
    return nil
  }
}

Предположим, у меня есть

class Person: Serializable {}

Я звоню BaseListDataSource где-то как

let dataSource = BaseListDataSource()
...

// Retrieve meta class type Person
if let personType = dataSource.modelMapping("Person") {
  // I want to get the first Person element in the Person list which I stored in dataSource
  let person = dataSource.getModel(of: personType, at: 0)
}

Я получаю сообщение об ошибке
Cannot invoke 'getModel' with an argument list of type '(of: Serializable.Type, at: Int)'.
Есть ли способ в Swift передать тип класса методу getModel(of:_at:_), как описано выше?

Обновление: я нашел способчтобы изменить код в моем ответе, и я изменил синтаксис кода вопроса.

1 Ответ

0 голосов
/ 24 декабря 2018

Мне потребовалось несколько дней, чтобы подумать об этой проблеме, и, наконец, я нашел способ изменить, как показано ниже:

protocol Serializable {} // Empty protocol

protocol AncestorListDataModel {
  func getGeneric(at index: Int) -> Serializable?
}

protocol ListDataModel: AncestorListDataModel {
  associatedtype T: Serializable
  var items: [T] { get }
}

extension ListDataModel {
  func getGeneric(at index: Int) -> Serializable? {
    if index >= 0 && index < items.count {
        return items[index]
    }

    return nil
  }
}

class BaseListDataModel<T>: ListDataModel where T: Serializable {
  ...
}

class BaseListDataSource: NSObject {
  private var listModels: [String: AncestorListDataModel] = [:]
  private(set) var modelMapping: [String: Serializable.Type] = [:]
  ...

  func getModel(of type: String, at index: Int) -> Serializable? {
    if let models = self.listModels[type] as? AncestorListDataModel {
        return models.getGeneric(at: index)
    }
    return nil
  }
}

И где-то мне нужно получить элемент типа Person в ListDataModel

let dataSource = BaseListDataSource()
...

// Retrieve meta class type Person
if let personType = dataSource.modelMapping("Person") {
  // I want to get the first Person element in the Person list which I stored in dataSource
  let person = dataSource.getModel(of: String(describing: personType), at: 0) as! Person
}

Моя идея заключается в создании протокола с именем AncestorListDataModel с обязательным методом getGeneric (at: _), который возвращает экземпляр, соответствующий Serializable, и ListDataModel должен его наследовать.Затем мне нужно привести этот экземпляр к типу, который я хочу использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...