ios - 数组中的 Swift 不同类型的泛型

标签 ios arrays swift generics

所以我正在为 UITableView 创建一些 View 模型。表格有不同的单元格类型,所以我使用了泛型,但是将它们放入数组时出现了一些问题。

首先我定义了一个结构体:

private struct Section<E, C> where C: UITableViewCell {
    let cell: C.Type
    let rows: [E]
    let configure: (_ row: E, _ cell: inout C, _ index: Int) -> Void
}

然后我声明了一个数组:

private lazy var sections: [Any] = [
    Section(cell: TextFieldTableViewCell.self,
            rows: [
              TableRow(image: R.image.home.device.settings.name(),
                       title: R.string.localizable.deviceSettingsViewControllerElementDeviceName(),
                       content: device.name,
                       action: { _ in

              }),
              TableRow(image: R.image.home.device.settings.location(),
                       title: R.string.localizable.deviceSettingsViewControllerElementDeviceLocation(),
                       content: device.location,
                       action: { _ in

              })],
            configure: { row, cell, index in
    }),
    Section(cell: DeviceSettingsNightVisionTableViewCell.self,
            rows: [
              TableRow(image: R.image.home.device.settings.nightVision(),
                       title: R.string.localizable.deviceSettingsViewControllerElementNightVision(),
                       content: 0,
                       action: { _ in
              })],
            configure: { row, cell, index in
    })
  ]

问题是:

  1. 我无法指定数组的类型,因为它们实际上是不同的泛型。
  2. 如果我使用[Any]作为数组的类型,那么每次取一个元素,我都必须将其转换为对应的类型,这与我最初的设计不一致。
  3. 我做了一些搜索,意识到我可能需要使用协议(protocol)来解决问题,但我尝试了很多次都失败了。

我期望的结果是,当我取一个元素时,我可以在不进行转换的情况下正确获取它的类型。

我目前的做法是这样的:

numberOfRowsInSection: 中,

switch section {
        case 0:
          return (self.sections[section] as! Section<TableRow, TextFieldTableViewCell>).rows.count
        case 1:
          return (self.sections[section] as! Section<TableRow, DeviceSettingsNightVisionTableViewCell>).rows.count
        default:
          return 0
        }

显然不够优雅,请问是否有更好的解决方案,任何帮助或建议都非常感谢。

最佳答案

您可以为您的行对象使用协议(protocol),并使用标识符而不是类型,我不完全确定这会完全解决您的问题,但您可以尝试一下:

protocol CellProtocol where Self: UITableViewCell {
    func bind(_ object: RowProtocol)
}

protocol RowProtocol {

}

struct Row1: RowProtocol {

}

struct Row2: RowProtocol {

}

private struct Section {
    let cellIdentifier: String
    let rows: [RowProtocol]
    let configure: (_ row: RowProtocol, _ cell: inout UITableViewCell, _ index: Int) -> Void


}

private lazy var sections: [Section] = [
    Section(cellIdentifier: "cell1",
            rows: [Row1()],
            configure: { row, cell, index in
    }),
    Section(cellIdentifier: "cell2",
            rows: [Row2()],
            configure: { row, cell, index in
    })
]

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if let cell = tableView.dequeueReusableCell(withIdentifier: sections[indexPath.section].cellIdentifier, for: indexPath) as? CellProtocol {
        cell.bind(sections[indexPath.section].rows[indexPath.row])
    }
}

让你自定义的cell类符合CellProtocol,然后在bind函数里面,尝试将RowProtocol转换成Row1 Row2 获取它们的值。

我也不确定您将如何在该部分对象内部进行配置,感觉不对,我宁愿让单元格类自行处理配置。

关于ios - 数组中的 Swift 不同类型的泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51392762/

相关文章:

ios - CoreData - 在哪里包含对对象的引用?

ios - 应用程序更新时的 NSUserDefaults 行为

java - 尝试使用 input.nextLine() 用用户输入(字符串)填充数组,但打印输出两次并且第一次不要求输入

ios - Alamofire 在解包 Optional 值时意外发现 nil

ios - 当另一个函数结束时运行一个函数,iOS,Swift

arrays - 尼姆 : advantage of using array over seq?

arrays - 为什么 *S Slice 可以由文字 S 开头?

ios - 关闭相机并返回应用程序需要很长时间

swift - 使用 AVAssetExportSession 将 MP4 转换为 WAV

swift - 从 native MacOS 应用程序访问 Web 浏览器选项卡并读取网站信息