Создайте универсальный класс TableView DataSource - PullRequest
0 голосов
/ 18 апреля 2019

Я хочу создать универсальный класс DataSource TableView, который содержит массив ConfigureModel:

protocol ConfigureModel {
    associatedtype ModelType
    var name: String { get set }

    var modelDescription: String { get }
}

Я также хочу, чтобы ячейка TableView была универсальной:

class ConfigureCell<ConfigureType>: UITableViewCell, Configure {
    func configure<Model: ConfigureModel>(with value: Model) where ConfigureType == Model.ModelType {
        let description = value.modelDescription

        print("ConfigureCell description: \(description)")
    }
}

поэтому я заставил ConfigureCell принять общий протокол Configure:

protocol Configure {
    associatedtype ConfigureType

    func configure<Model: ConfigureModel>(with value: Model) where Model.ModelType == ConfigureType
}

Теперь я могу заставить модель принять протокол ConfigureModel для использования в классе ConfigureCell:

struct Tag {
    ....
}
extension Tag: ConfigureModel {
    typealias ModelType = Tag
}

Это отлично работает.Теперь, чтобы сделать ObjectDataSource generic:

class ObjectDataSource<T: ConfigureModel>: NSObject, UITableViewDataSource, UITableViewDelegate {
    var values: [T] = []
    ....
    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let item = self.values[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: "TagCell", for: indexPath) as! ConfigureCell<T>
        cell.configure(with: item)

, и вот у меня есть проблема, которую я пытался решить в течение многих часов.Последний оператор cell.configure(with: item Xcode показывает ошибку: Instance method 'configure(with:)' requires the types 'T' and 'T.T' be equivalent

Я понимаю, что должен сделать общее предложение where в классе, но у меня возникают проблемы с выяснением, что это должно быть.

class ObjectDataSource<T: ConfigureModel>: NSObject, UITableViewDataSource, UITableViewDelegate
    where T == ???? {

Я создал игровую площадку Xcode, которая работает, но закомментированные части не работают.Вы можете получить его здесь: GenericDataSource Xcode PlayGround

1 Ответ

0 голосов
/ 18 апреля 2019

Я также хочу, чтобы ячейка TableView была общей

Вам это просто не нужно.Вы уже определили метод configure(with:) как общий.Не нужно делать сам класс универсальным.


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

class ConfigureCell: UITableViewCell {
    func configure<Model: ConfigureModel>(with value: Model) {
        let description = value.modelDescription()

        print("ConfigureCell description: \(description)")
    }
}

class ObjectDataSource<T: ConfigureModel>: NSObject, UITableViewDataSource {
    var values: [T] = []

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return values.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let item = self.values[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: "TagCell", for: indexPath) as! ConfigureCell
        cell.configure(with: item)
        return cell
    }
}
...