iOS14下UITableViewDiffableDataSource不必要重复渲染问题排查
iOS14.3与iOS15.5中UITableViewDiffableDataSource单元格重渲染差异的原因
你遇到的问题本质是UITableViewDiffableDataSource在iOS15前后的内部实现逻辑差异,核心在于系统判断数据是否需要触发单元格更新的校验规则不同:
iOS15+的逻辑:严格依赖自定义的
hash与==
iOS15及以后,DiffableDataSource在计算数据差异时,完全以你实现的hash()方法和Equatable协议的==方法结果为准。因为你刻意在这两个方法中排除了currentValue属性,所以即使该属性变化,系统会判定模型实例“未变更”,因此不会触发单元格的重新渲染,表现符合你的预期。iOS14及更早的逻辑:额外的结构体全量对比
iOS14的DiffableDataSource内部,除了检查hash和==的结果,还会额外对结构体的全量属性进行对比。由于结构体是值类型,只要currentValue发生变化,整个结构体实例就会被视为新的实例——哪怕你的hash和==认为新旧实例相等,系统依然会判定数据有变更,进而触发单元格的重新渲染。这就是为什么你看到哈希值一致、==也没被调用,但单元格还是被重复渲染的原因。
适配建议
如果需要在iOS14上实现和iOS15一致的行为,可以考虑:
- 将模型从结构体改为类(引用类型):引用类型的实例更新属性时不会生成新实例,只要
hash和==判定相等,系统就会认为数据未变更,不会重渲染单元格。 - 若坚持使用结构体,可通过自定义缓存逻辑,确保更新
currentValue时复用原有结构体实例的引用(但值类型的特性决定了这种方式实现成本较高,不推荐)。
内容的提问来源于stack exchange,提问作者Avi
相关产品推荐
相关产品推荐

