swift 如何在主线程中有效地使用从后台线程获取的对象?

flvtvl50  于 2023-10-15  发布在  Swift
关注(0)|答案(1)|浏览(135)

我需要在我的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)吗?尤其是在有很多对象的情况下。

在后台将获取的对象转换为结构体,然后安全地将它们传递给主线程,这样会更有效吗?但在这种情况下,我每次想修改对象时,不是都要获取它吗?我上网查了一下,但找不到合适的解释。
我很欣赏任何关于这一点的见解。谢谢

xbp102n0

xbp102n01#

你好像把事情搞得很复杂。一般来说,您不应该将特定的托管对象示例传递到SwiftUI中。相反,您应该将托管对象上下文传递到SwiftUI中,然后使用FetchRequest property wrapper来获取对象。一个获取请求可以有一个 predicate ,但是如果你试图在托管对象上下文中获取MyEntity的所有示例,你可以不使用这个 predicate 。
当对象被添加到托管对象上下文中或从托管对象上下文中删除时,您的UI将自动更新。例如,如果您正在使用一个API,它提供对位于某个服务器上的远程对象的访问,您可以下载数据并将其导入到后台线程中的托管对象,保存托管对象上下文,对象将仅显示在您的UI中。

相关问题