带有自我转换的Swift通用扩展

时间:2019-02-15 14:32:05

标签: ios swift generics

目标是像

那样使单元出队
 let cell = CustomCollectionViewCell.dequeueReusable(collectionView, for: indexPath)

我正在尝试

class func dequeueReusable<T: UICollectionViewCell>(_ collectionView: UICollectionView, for indexPath: IndexPath) -> T {
    return collectionView.dequeueReusableCell(withReuseIdentifier: self.reuseID, for: indexPath) as! T
}

但是它返回UICollectionViewCell,而不是CustomCollectionViewCell。

如何实现?

1 个答案:

答案 0 :(得分:1)

您对dequeueReusable的呼叫永远不需要T的任何特定类型,因此选择了最通用的类​​型。但是,您想要的类型是Self(当前子类的类型)。

编写此代码的自然方法(但略有错误)是:

class func dequeueReusable(_ collectionView: UICollectionView, 
                           for indexPath: IndexPath) -> Self {
    return collectionView.dequeueReusableCell(withReuseIdentifier: self.reuseID,
                                                              for: indexPath) as! Self
}

老实说,我不知道为什么这行不通。 Self不能在as! Self构造中使用。但是,可以使用通用包装器来欺骗它:

func cast<T>(_ value: Any) -> T { return value as! T }

有了它,您就可以获得工作版本:

class func dequeueReusable(_ collectionView: UICollectionView,
                           for indexPath: IndexPath) -> Self {
    return cast(collectionView.dequeueReusableCell(withReuseIdentifier: self.reuseID, 
                                                   for: indexPath))
}