当协议类型已经具有类型特定的约束时,“只能用作一般约束”错误

时间:2018-12-19 10:41:18

标签: swift generics

我有一个UICollectionViewCell子类,该子类实现了如下协议:

protocol SpecialCell where Self: UICollectionViewCell {
  associatedType T: SpecialCellViewModel  // protocol
  var viewModel: T? { get set }
}

在使单元出队时,我必须将UICollectionViewCell强制转换为我的SpecialCell兼容类型,以便访问viewModel属性。我正在这样尝试:

let cell = collectionView.dequeueReusableCell[...]
(cell as? SpecialCell).viewModel = viewModel[...]

现在,尽管协议实际上保证Self必须为UICollectionViewCell类型,但第二行现在使编译器抛出“只能用作一般约束[...]”错误消息。为什么我仍然会收到此错误消息,还有其他解决方法吗?

1 个答案:

答案 0 :(得分:1)

您不能使用协议类型为associatedType的变量,因为Swift编译器不知道相关的类型是什么(只是知道它具有符合标准的T类型某种协议,但它不知道T到底是什么类型)。您必须使用具体类型(符合SpecialCell协议的类),该类型具有与SpecialCell协议的通用参数相关的具体类型。

而且,我认为强制where Self: UICollectionViewCell没有任何用处。您必须创建一个符合UICollectionViewCell的{​​{1}}子类才能使用您的协议。

我猜测您有几个符合SpecialCell的单元格子类,这就是您要以此方式编写代码的原因。不幸的是,除了在使用SpecialCell的协议时,除了将每个出队单元格转换为其具体类型外,在Swift中没有其他方法可以实现。

相关问题