![](/img/trans.png)
[英]Storing Generic Objects in a Heterogeneous Array and retrieving object parameter as the correct type
[英]Heterogeneous Array of generic object where T is different
这是我的类BaseSection
实现Collection
,它看起来像这样:
class BaseSection<T:Equatable> {
var items:[T]?
required init(items:[T]){
self.items = items
}
}
let sectionTop = BaseSection<TopItem>(items:["foo","bar","yo"])
let sectionBottom = BaseSection<BottomItem>(items:["foo","bar","yo"])
对于此演示,我正在构造可Equatable
的字符串对象部分,但此处未列出具有String
集合实现的一个属性的项目构造对象。 我需要将两个对象都保存在数组中,即使它们的基类相同,也无法做到。
let sections = [sectionTop, sectionBottom]
heterogeneous collection literal could only be inferred to '[Any]' add explicit type annotation....
即时通讯花了很多时间解决许多问题,但在这里无法实现我的目标。 任何帮助将非常感激
Edit: I have uploaded the sample code to gitHub so you can get a better grasp of what im doing
快速自定义通用类型中的becos都是不变的,这意味着BaseSection<TopItem>
和BaseSection<BottomItem>
没有关系,因此二者的唯一常见类型是Any
,您可以按照评论中的链接获取更多信息,作为摘要
另外,Arrays / Dict是struct,这意味着它们是按值传递的,因此将它们视为协方差是安全的
您似乎正在构建的是一种随着数据变化自动执行表视图更改的机制。 很普通的。 我强烈建议您查看ListDiff ,这是计算更改的有用起点。 (在我自己的代码中,我使用重写版本的ListDiff,因此此处的示例未经测试,但应该非常接近。)
目标是创建一组更新操作(从ListDiff示例复制):
import ListDiff
extension Int : Diffable {
public var diffIdentifier: AnyHashable {
return self
}
}
let o = [0, 1, 2]
let n = [2, 1, 3]
let result = List.diffing(oldArray: o, newArray: n)
// result.hasChanges == true
// result.deletes == IndexSet(integer: 0)
// result.inserts == IndexSet(integer: 2)
// result.moves == [List.MoveIndex(from: 2, to: 0), List.MoveIndex(from: 1, to: 1)]
// result.changeCount == 4
这里重要的是您要进行一系列的删除,插入和移动操作。 您可以通过以下几行将其应用于表视图:
extension UITableView {
func applyChanges(from changeset: Result, forSection section: Int = 0) {
beginUpdates()
let deletes = changeset.deletes.map { IndexPath(row: $0, section: section) }
deleteRows(at: deletes, with: .bottom)
let inserts = changeset.deletes.map { IndexPath(row: $0, section: section) }
insertRows(at: inserts, with: .none)
for move in changeset.moves {
guard !changeset.deletes.contains(move.from) else { continue }
moveRow(at: IndexPath(row: move.from, section: section),
to: IndexPath(row: move.to, section: section))
}
endUpdates()
}
}
这里的关键点是对于动画,您只需要索引路径。 您实际上并不需要数据。 因此,计算索引路径并传递它们。 无需泛型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.