创建 ModelContext 的成本有多高?

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

在 Swift 中使用现代并发时,我注意到了

  • ModelContainer
    Sendable
  • ModelContext
    不是

这最终意味着在分离的

Task
中安排工作,如果我尝试这样做,编译器会不断抱怨与不可发送类型跨越参与者边界

  • 为我的演员创建一个单一的上下文
  • 只需使用所有
    .mainContext
    s
     上可用的 
    ModelContainer

因此,我所采取的方法是在需要时创建一个新的上下文,并在

ModelContainer
中添加一个方便的扩展:

extension ModelContainer {
    func makeNewContext() -> ModelContext? {
        return ModelContext(self)
    }
}

然后我只要跨越演员边界就创建新的上下文:

actor Example {
    private var container: ModelContainer? // initialized from init
    // private lazy var context = container?.makeNewContext() // cannot be used from detached tasks
    [...]

    nonisolated func exampleFunc() async throws {
        Task.detached {
            // cannot use `.mainContext` here because this isn't the main actor

            var context = await self.container?.makeNewContext()
            var items = try context?.fetch(FetchDescriptor<SomeModelClass>())

            [...]
        }

        [...]
    }
}

这是一个好的做法吗?提到的任何其他选项都是编译器的警告/错误。 SwiftData 似乎不鼓励在并发域之间重用上下文。

swift swift-data
1个回答
0
投票

解决方案是使用带有

ModelActor
宏的特定 SwiftData actor,该宏将保存自己的
ModelContext
实例。

@ModelActor
actor Example {
    func exampleFunc() async throws {
        var items = try modelContext.fetch(FetchDescriptor<TestModel>())
    }
}

宏将创建一个带有

ModelContainer

的 init
let actor = Example(container: modelContext.container)
© www.soinside.com 2019 - 2024. All rights reserved.