制作一个通用的 TableView 数据源 class

Make a generic TableView DataSource class

我想创建一个通用的 TableView 数据源 class,它包含一个 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 class:

中使用
struct Tag {
    ....
}
extension Tag: ConfigureModel {
    typealias ModelType = Tag
}

这很好用。现在使 ObjectDataSource 通用:

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

我知道我必须在 class 中创建一个通用的 where 子句,但我很难找到它应该是什么。

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

我制作了一个可以运行的 Xcode 游乐场,但注释掉的部分不起作用。你可以在这里得到它:GenericDataSource Xcode PlayGround

I also want the TableView cell to be generic

你根本不需要那个。您已经将 configure(with:) 方法定义为通用方法。无需将 class 本身设为通用。


鉴于上述陈述,如果您不介意的话,下面是您的简单实现:

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
    }
}