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

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

我需要在我的 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:)
。这是否也会有阻塞主线程的风险(恶化用户体验),尤其是在有很多对象的情况下?

将后台获取的对象转换为结构体,然后安全地传递到主线程会更高效吗?但在这种情况下,我是否每次想要修改对象时都必须获取对象?我上网但找不到正确的解释。

我很感激对此的任何见解。谢谢你。

swift core-data
1个回答
0
投票

你似乎让事情变得比需要的更困难。一般来说,您不应该将特定的托管对象实例传递到 SwiftUI 中。您应该将托管对象上下文传递到 SwiftUI,然后使用 FetchRequest 属性包装器 来获取对象。获取请求可以有谓词,但如果您尝试获取托管对象上下文中的 MyEntity 的所有实例,则可以将其保留。

当对象添加到托管对象上下文或从托管对象上下文中删除时,您的 UI 将自动更新。例如,如果您正在使用一个 API,该 API 提供对某个服务器上的远程对象的访问,您可以下载数据并将其导入到后台线程中的托管对象中,保存托管对象上下文,然后对象将出现在你的用户界面。

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