【问题标题】:Protocols with Associated Types in array - alternative solutions数组中具有关联类型的协议 - 替代解决方案
【发布时间】:2018-07-25 03:41:41
【问题描述】:

考虑一个例子:

protocol CellConfigurator {
  var cellClass: UICollectionViewCell.Type {get}
  func configure(cell: UICollectionViewCell)
}

class AppleCell: UICollectionViewCell {
  let title = UILabel()
}

class AppleCellConfigurator: CellConfigurator {
  let cellClass: UICollectionViewCell.Type = AppleCell.self
  func configure(cell: UICollectionViewCell) {
    guard let cell = cell as? AppleCell else {return}
    cell.title.text = "AAPL"
  }
}

我可以使用上述模式来封装UICollectionViewCell的实际类型,使用如下(伪代码):

func cellAt(indexPath: IndexPath) -> UICollectionViewCell {
  let configurator = configurators[indexPath]
  let cell = collectionView.dequeueReusableCell(identifier: String(describing: configurator.cellClass))
  configurator.configure(cell)
  return cell
}

我期待摆脱对每个符合 CellConfigurator 的单元进行类型转换的必要性,例如,使用具有关联类型的协议:

protocol CellConfigurator {
  associatedtype Cell
  func configure(cell: Cell)
}

class AppleCell: UICollectionViewCell {
  let title = UILabel()
}

class AppleCellConfigurator: CellConfigurator {
  typealias Cell = AppleCell
  func configure(cell: Cell) {
    cell.title.text = "AAPL"
  }
}

但是,由于错误,我无法将它们放在一个数组中:“Protocol 'SomeProtocol' 只能用作通用约束,因为它具有 Self 或关联的类型要求”。

有没有办法实现这两个目标:

  1. 对于任何CellConfigurator 都有一个带有UICollectionViewCell 参数类型的函数?
  2. 在特定配置器的函数中具有具体类型

【问题讨论】:

  • 我认为您可以创建一个符合CellConfigurator 的通用基类,然后AppleCellConfigurator 将从该类继承。
  • @Kamran 我认为这是一个很好的类型擦除案例。

标签: swift generics protocols


【解决方案1】:

您可以在 CellConfigurator 中使用相关类型:

protocol CellConfigurator: class {
    associatedtype CellType where CellType: UICollectionViewCell

    func configure(cell: CellType)
}

class AppleCell: UICollectionViewCell {
    let title = UILabel()
}

class AppleCellConfigurator: CellConfigurator {
    typealias CellType = AppleCell

    func configure(cell: CellType) {
        cell.title.text = "AAPL"
    }
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-24
  • 2021-09-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多