Swift排序规则SortDescriptor
Swift排序规则SortDescriptor

Swift排序规则SortDescriptor

SwiftData数据查询依赖FetchDescriptor,FetchDescriptor依赖SortDescriptor进行排序。

基本形式

SortDescriptor(\.property, order: .forward)

\.property是排序的属性的KeyPath。

order是顺序:.forward = 升序,.reverse = 降序。

使用方法

1、排序字段

SortDescriptor可以排序文本、数字、日期、可选类型(nil排在最前或最后,具体取决于排序方向)。

例如:

let sortByAmount = SortDescriptor(\PiggyBank.amount, order: .reverse) // 金额从大到小

2、多重排序

SwiftData可以提供多个SortDescriptor排序。

FetchDescriptor<PiggyBank>(
    sortBy: [
        SortDescriptor(\.isPrimary, order: .reverse),
        SortDescriptor(\.creationDate, order: .forward)
    ]
)

isPrimary的存钱罐排在前面,再按创建时间从早到晚排序。

3、可选值的排序行为

当属性是 Optional 类型时:

.forward 时,各类型的“nil 最前”。

.reverse 时,“nil 最后”。

注意事项

1、无法排序Bool类型

如果在SortDescriptor中,尝试排序Bool类型,会触发类型推断失败,让编译器错误地落到 Foundation 的 NSSortDescriptor 版本上。于是报出需要继承 NSObject 的错误。

Initializer 'init(_:order:)' requires that 'PiggyBank' inherit from 'NSObject'

例如:

let fetchRequest = FetchDescriptor<PiggyBank>(
    sortBy: [
        SortDescriptor(\.isPrimary, order: .reverse),   // 发生报错
        SortDescriptor(\.creationDate, order: .reverse)
    ]
)

因为isPrimary是布尔类型,因此发生报错。

解决方案:给Bool添加扩展,使其遵守Comparable协议:

extension Bool: Comparable {
    public static func < (lhs: Bool, rhs: Bool) -> Bool {
        // 定义 false 小于 true (即 0 < 1)
        return !lhs && rhs
    }
}

SwiftData就可以通过编译并正确生成SQL排序指令。

注:数据库层面(SQLite)本身是支持 Boolean 排序的(0和1),这个扩展只是为了通过 Swift 的类型检查。

总结

SortDescriptor配合FetchDescriptor,实现数据的排序规则。

SortDescriptor排序在数据库层面执行,不是Swift层面对数组排序,因此性能非常好,多重排序仍然可控。

升序和降序的区别在于:

升序:从小到大排序,数值小的排在前面,数值大的排在后面。

0 → 1 → 2

降序:从大到小排序,数值大的排在前面,数值小的排在后面。

2 → 1 → 0

相关文章

SwiftData查询描述符FetchDescriptor:https://fangjunyu.com/2025/11/20/swiftdata%e6%9f%a5%e8%af%a2%e6%8f%8f%e8%bf%b0%e7%ac%a6fetchdescriptor/

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注