SwiftData 使用 #Preview

问题描述 投票:0回答:1

我有一个简单的逻辑,可以将项目添加到一对多关系中。

        let modelA = ModelA.createDummyData()
        modelContext.insert(modelA)
        
        // simply create ModelB() then modelB.modelA = modelA
        let modelB = ModelB.createDummyData(for: modelA)
        
        print(modelA.modelBs.count) // HERE = 1

        do {
            try modelContext.save()
        } catch {
            fatalError("[ERROR] \(error)")
        }
        
        let t = try! modelContext.fetch(FetchDescriptor<ModelA>()).first!
        print(t.modelBs.count) // HERE = 2 !!!

您会看到,保存后,modelB 的数量就重复了。这些重复项是唯一的项目,用

UUID()
进行验证(我没有创建)。我还比较了保存之前和之后的相同模型。也得到了其
id = UUID()
的验证。

关系的定义遵循最佳实践和示例,仅在一侧添加

@Relationship

@Model public class ModelA {
    @Relationship(deleteRule: .cascade, inverse: \ModelB.modelA) public var modelB: [ModelB] = []
}

@Model public class ModelB {
    public var modelA: ModelA?
}

我尝试使用 SQL 调试,但并没有真正发现生成的 SQL 有用。我还从 ModelB

init()
函数登录,发现只进行了 1 个调用。

为什么会发生这种情况?如何调试?

swift swift-data
1个回答
0
投票

对于遇到此问题的任何人,以下是我的发现。

  • 这几乎完全发生在
    #Preview
    上,在模拟器运行中很少发生(只有一两次,很难重现)
  • 到目前为止,这只发生在内存存储中
  • 我偶尔可以让
    .fetch()
    返回正确的 ModelB 计数,但是当在视图中传递时,在
    .onAppear
    中计数会再次加倍;我什至见过数量增加三倍的案例!
  • .unique
    字段上添加
    id
    约束没有帮助
  • 我的解决方案:由于这仅用于预览和调试,因此我在插入之前使用
    ModelContext.delete(model:)
    添加了手动重置,现在计数是正确的

有时,

#Preview
中的代码在更改代码后会运行两次,我认为内存存储可能不会在这些运行之间重置,但即使是这种情况,我也应该得到 2 个 ModelAs,每个 ModelA 带有 1 个 ModelB,而不是1 个 ModelA 和 2 个 ModelB

我怀疑这是 SwiftData 内存存储中的一个错误(或者它与预览机制相互作用的方式),因为我的旧 Core Data 有一个类似的内存存储用于预览,但我从未见过这样的东西。我一直在将 Core Data 代码迁移到 SwiftData,这让我困惑了很长一段时间。

© www.soinside.com 2019 - 2024. All rights reserved.