我有以下型号:
@Model
class Game {
var name: String
var firstReleasedOn: Date?
@Relationship(deleteRule: .cascade, inverse: \QueueEntry.game)
var queueEntry: QueueEntry?
init(
name: String,
firstReleasedOn: Date?
) {
self.name = name
self.firstReleasedOn = firstReleasedOn
}
}
@Model
public class QueueEntry {
var game: Game?
var createdOn: Date
var order: Int
init(order: Int) {
self.createdOn = .now
self.order = order
}
}
我想用按游戏发行日期排序的所有条目填充
List
,所以我有以下内容:
struct QueueView: View {
@Query(sort: [SortDescriptor(\QueueEntry.game?.firstReleasedOn)])
private var entries: [LocalData.QueueEntry]
var body: some View {
List(entries) { entry in
Text(entry.game.name ?? "")
}
}
}
在 Debug 中运行上面的代码是完全没问题的。但是,在 Release 中运行会引发以下错误:
SwiftData/DataUtilities.swift:65:致命错误:在带有字段 [SwiftData.Schema.PropertyMetadata(name: "game", keypath: \QueueEntry.
, defaultValue: nil) 的 QueueEntry 上找不到 \QueueEntry. ?. ,元数据:nil),SwiftData.Schema.PropertyMetadata(名称:“createdOn”,键路径:\QueueEntry. ,defaultValue:nil,元数据:nil),SwiftData.Schema.PropertyMetadata(名称:“order”,键路径:\QueueEntry . ,默认值:nil,元数据:nil)]
QueueEntry.game
需要是可选的,因为将其设置为非可选并尝试在 init 中创建关系会导致 NSInvalidArgumentException
,推理由 Joakim Danielson here 解释。
这只是 SwiftData 的一个 bug/问题,需要 Apple 解决吗?我可以实施其他一些解决方法来保持
Game
和 QueueEntry
之间关系的完整性吗?
解决方法。 在 init 中,创建一个排序常量并更新查询。
@Query private var entries: [QueueEntry]
init() {
let sort = SortDescriptor(\QueueEntry.game?.firstReleasedOn)
_entries = Query(sort: [sort])
}
注意:如果未创建排序常量,则 init 会像
_entries = Query(sort: [SortDescriptor(\QueueEntry.game?.firstReleasedOn)])
一样更新。这会崩溃。