提问人:ngb 提问时间:11/13/2023 最后编辑:ngb 更新时间:11/14/2023 访问量:63
如何使用 swift 并发模型从 SwiftUI 视图安全地访问 Core 数据 NSManagedObject 属性?
How to safely access Core data NSManagedObject attributes from a SwiftUI view using swift concurrency model?
问:
如何使用 swift 并发模型从 SwiftUI 视图安全地访问核心数据 NSManagedObject 属性。
我的理解是,我们需要将对NSManageObject属性的任何访问都包含在其中,但是如果我在视图中的任何位置使用它,无论是在or或修饰符中,我都会收到以下警告或错误:await context.perform {}.
body(),
init()
.task()
for 修饰符或(如果在任何范围内).task{}
Task {}:
在主执行组件隔离的上下文之外传递不可发送类型“NSManagedObjectContext.ScheduledTaskType”的参数可能会引入数据争用 即使我仅为此访问创建新上下文,也会发生这种情况。
如果在 或body()
init():
“await”在不支持并发的函数中
但是我们不能将 body 或 init() 设置为异步
代码示例如下:
var attributeString: String = ""
let context = PersistentStore.shared.persistentContainer.newBackgroundContext()
await context.perform {
let backgroundObject = context.objectWithID(objectID)
attributeString = backgroundObject.attribute!
}
答:
1赞
Joakim Danielson
11/13/2023
#1
你的代码不完整,但像这样的东西应该可以工作。创建一个函数来执行提取,这个函数也是你创建后台上下文的地方
func fetchObject(/* params... */) async -> SomeManagedObject {
let context = PersistentStore.shared.persistentContainer.newBackgroundContext()
return await context.perform {
/* fetch */
return fetchedObject
}
}
然后在视图中调用该函数并使用它
.task {
let managedObject = await fetchObject(/* params */)
attributesString = managedObject.attribute
1赞
malhal
11/13/2023
#2
诀窍是获取 before your perform 块,然后在 perform 中,您只需要使用该 ID 在后台上下文中再次找到对象。现在,您有一个可以从后台安全访问的对象,例如nsmanagedObject.objectID
let objectID = nsmanagedObject.objectID
var attributeString: String = ""
let context = PersistentStore.shared.persistentContainer.newBackgroundContext()
await context.perform {
let backgroundObject = context.objectWithID(objectID)
attributeString = backgroundObject.attribute!
}
评论
0赞
ngb
11/14/2023
你是对的,我需要使用对象 ID 来重新获取我忽略的对象,将其包含在问题的简化代码中,当它在视图之外时,这有效。但是在 SwiftUI 视图中,警告/错误位于 await context.perform 行上。
0赞
malhal
11/14/2023
.task 是放置异步代码的地方,对我有用
评论