swift 使用Coredata在后台线程中获取数据

jdzmm42g  于 2023-06-21  发布在  Swift
关注(0)|答案(1)|浏览(155)

当在后台环境中从数据库中获取国家时,我面临着从Core Data中的执行块访问结果的问题。下面是代码片段:

actor Repository {
    @available(iOS 15.0, *)
    private func fetchAllCountries() async -> [MCCountry]? {
        let request = getFetchRequest()
        let backgroundContext = container.newBackgroundContext()
        do {
            let result = try await backgroundContext.perform {
                let countries = try backgroundContext.fetch(request) as? [MCCountry]
                let attributeValue = countries?.first?.countryCode
                debugPrint("Country code \(String(describing: attributeValue))") // returns value
                return countries
            }
            debugPrint("Country \(String(describing: result))") // crashes here
            return result
        } catch {
            debugPrint("error \(error)")
            return nil
        }
    }
}

来电者:

Task {
             await repository.fetchCountries { result in
                if let result {
                    for value in result {
                        debugPrint("Value is \(String(describing: value.countryCode))") //returns nil
                    }
                }
            }
        }

问题是,即使我可以访问perform块中的结果,从backgroundContext.perform返回的结果似乎是不可访问的。当我试图访问块后的结果时,我遇到了EXC_BAD_ACCESS错误。我期望从perform方法接收结果并在fetchAllCountries方法中立即返回它。
我是不是在理解中遗漏了什么?我不应该期待perform块的结果吗?有人能帮我找出代码的错误吗?
先谢谢你。

qkf9rpyu

qkf9rpyu1#

你正在获取的backgroundContext在你的函数执行后被释放。然后在它上面获取的所有对象将不再有效。
如果获取的目的是显示数据,那么它必须发生在viewContext上。
如果你有一个大的查询来预处理你的数据,你可以在异步获取中返回ObjectID而不是对象,然后创建一个 predicate 来获取包含在objectID中的对象和viewContext上的对象,以实际获取要显示的对象。

相关问题