我需要在我的UI中使用NSManagedObjects
示例。据我所知,在后台线程中获取后,与对象本身相比,NSManagedObjectID
可以安全地传递给主线程,然后在**existingObject(with:)
方法中使用,以获取UI中使用的对象。然而,我不清楚这种方法的效率,特别是在主线程中为每个对象调用existingObject(with:)
**。
如下面的例子:
let backgroundContext = persistentContainer.newBackgroundContext()
let mainContext = persistentContainer.viewContext
backgroundContext.perform {
do {
let fetchRequest: NSFetchRequest<MyEntity> = MyEntity.fetchRequest()
let fetchedObjects = try backgroundContext.fetch(fetchRequest)
let objectIDs = fetchedObjects.map { $0.objectID }
DispatchQueue.main.async {
let mainThreadObjects = objectIDs.map { mainContext.object(with: $0) as! MyEntity }
}
} catch {
// Handle error
}
}
existingObject(with:)
只是一个更快的获取请求版本,还是本质上是一个即时操作?我的意思是,虽然我们在后台线程上获取对象以避免阻塞主线程,但我们最终还是在主线程上为每个对象使用existingObject(with:)
。这不会也有阻塞主线程的风险(恶化UX)吗?尤其是在有很多对象的情况下。
在后台将获取的对象转换为结构体,然后安全地将它们传递给主线程,这样会更有效吗?但在这种情况下,我每次想修改对象时,不是都要获取它吗?我上网查了一下,但找不到合适的解释。
我很欣赏任何关于这一点的见解。谢谢
1条答案
按热度按时间xbp102n01#
你好像把事情搞得很复杂。一般来说,您不应该将特定的托管对象示例传递到SwiftUI中。相反,您应该将托管对象上下文传递到SwiftUI中,然后使用FetchRequest property wrapper来获取对象。一个获取请求可以有一个 predicate ,但是如果你试图在托管对象上下文中获取MyEntity的所有示例,你可以不使用这个 predicate 。
当对象被添加到托管对象上下文中或从托管对象上下文中删除时,您的UI将自动更新。例如,如果您正在使用一个API,它提供对位于某个服务器上的远程对象的访问,您可以下载数据并将其导入到后台线程中的托管对象,保存托管对象上下文,对象将仅显示在您的UI中。