Swift中SortDescriptor使用Int枚举KeyPath时初始化报错
报错原因
SortDescriptor的默认初始化器没有针对遵循RawRepresentable的枚举类型做适配,仅原生支持Int16、String这类直接实现了Comparable协议的基础类型,因此传入指向枚举属性的KeyPath时,编译器无法找到匹配的初始化方法就会抛出报错。
而NSSortDescriptor基于ObjC运行时的KVC机制实现,会自动读取枚举的原始值完成排序逻辑,因此不会触发编译错误。
可行适配方案
不需要额外存储类似rawCategory的冗余属性,任选以下一种方案即可:
- 轻量方案:初始化时手动指定排序依据为枚举原始值
直接在KeyPath后链式访问枚举的rawValue属性即可,不需要写额外扩展,适配成本最低:// 按枚举原始值正序排列 let categorySortDescriptor = SortDescriptor(\Book.category.rawValue, order: .forward) - 通用方案:扩展SortDescriptor全局支持RawRepresentable枚举
如果项目中存在多个需要排序的枚举类型,写一次扩展即可让所有带可比较原始值的枚举直接支持SortDescriptor初始化,不需要每次手动拼接.rawValue:
扩展添加完成后,原报错代码extension SortDescriptor where Value: RawRepresentable, Value.RawValue: Comparable { init(_ keyPath: KeyPath<Root, Value>, order: SortOrder = .forward) { self.init(keyPath, comparator: { $0.rawValue < $1.rawValue }, order: order) } }let categorySortDescriptor = SortDescriptor(\Book.category)即可直接编译通过,排序逻辑和直接使用原始值排序完全一致。
注意:如果枚举的排序逻辑不是按照原始值大小排列,只需要修改扩展里的comparator闭包逻辑,自定义排序规则即可。
内容的提问来源于stack exchange,提问作者alpennec
相关产品推荐
相关产品推荐

