介绍
FlexibleDiff 是一个用于 Swift 的简单集合 diffing μ框架,允许独立定义身份和相等性,用于 diffing。
对于一般业务关注点,两个实例之间完全不等并不一定意味着在身份方面的不等 - 这仅仅意味着如果两个实例的身份相同,所持数据已更改。然而,由于大多数 diffing μ框架仅依赖 Equatable
要求,它们受限于此,无法表达常见于交互式应用中的“相同但不同”的场景。
FlexibleDiff 通过支持使用自定义的相等性和身份定义进行更改集计算来解决这个问题。
例如,给定以下定义
let previous: [Book]
let current: [Book]
struct Book: Equatable {
let isbn: String
var name: String
var publishedOn: [Date]
}
我们可能提供自定义的身份定义,并基于仅通过其 ISBN 识别的书籍,了解原地更改的书籍或不同位置的更改的书籍。
let changeset = Changeset(previous: previous,
current: current,
identifier: { book in book.isbn },
areEqual: Book.==)
与基于 Equatable
的传统 μ框架相比,改进的 diff 表达性允许执行更合适的集合视图动画。
除了灵活的 API 外,FlexibleDiff 还为常见用例提供了几个便利功能
Collection.Element |
通过标识符 | 通过比较 |
---|---|---|
AnyObject |
对象身份 | 对象身份 |
AnyObject & Equatable |
对象身份 | 对象身份或值相等。 |
AnyObject & Hashable |
对象身份,或值相等。 | 对象身份,或值相等。 |
Hashable |
值相等 | 值相等 |
入门
FlexibleDiff 以独立的 Xcode 项目形式提供,同时支持 Carthage 和 CocoaPods。
# Carthage
github "RACCommunity/FlexibleDiff"
# CocoaPods
pod "FlexibleDiff"
示例应用
Xcode 工作空间包含一个使用 FlexibleDiff 的示例应用。确保在 Xcode 中构建应用目标之前,运行 git submodule update --init
来获取依赖项。
算法说明
实现借鉴了 Paul Heckel 在其 1978 年论文“在文件之间隔离差异的技术”(https://dl.acm.org/citation.cfm?id=359467)中提出的流行的 O(n) diff 算法。该算法作为许多跨多个平台的框架的基础,包括但不限于 IGListKit。
许可证
在 MIT 许可证下授权。