gpt4 book ai didi

ios - CoreData 中的异步读取 - 使用 newBackgroundContext + FetchRequest 与 newBackgroundContext + NSAsynchronousFetchRequest 的区别?

转载 作者:行者123 更新时间:2023-12-05 03:31:58 25 4
gpt4 key购买 nike

似乎有两种方法可以在不阻塞主线程 UI 的情况下在 CoreData 中执行异步读取。


newBackgroundContext + NSFetchRequest

来源:https://www.advancedswift.com/core-data-background-fetch-save-create/

// Create a new background managed object context
let context = persistentContainer.newBackgroundContext()

// If needed, ensure the background context stays
// up to date with changes from the parent
context.automaticallyMergesChangesFromParent = true

// Perform operations on the background context
// asynchronously
context.perform {
do {
// Create a fetch request
let fetchRequest: NSFetchRequest<CustomEntity>

fetchRequest = CustomEntity.fetchRequest()
fetchRequest.fetchLimit = 1

let objects = try context.fetch(fetchRequest)

// Handle fetched objects
}
catch let error {
// Handle error
}
}

newBackgroundContext + NSAsynchronousFetchRequest

来源:https://www.marcosantadev.com/coredata_crud_concurrency_swift_2/

let privateManagedObjectContext = persistentContainer.newBackgroundContext()

// Creates a fetch request to get all the dogs saved
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Dog")

// Creates `asynchronousFetchRequest` with the fetch request and the completion closure
let asynchronousFetchRequest = NSAsynchronousFetchRequest(fetchRequest: fetchRequest) { asynchronousFetchResult in

// Retrieves an array of dogs from the fetch result `finalResult`
guard let result = asynchronousFetchResult.finalResult as? [Dog] else { return }

// Dispatches to use the data in the main queue
DispatchQueue.main.async {
// Do something
}
}

do {
// Executes `asynchronousFetchRequest`
try privateManagedObjectContext.execute(asynchronousFetchRequest)
} catch let error {
print("NSAsynchronousFetchRequest error: \(error)")
}

但是,请注意,如果我要启用标志 -com.apple.CoreData.ConcurrencyDebug 1,上面的代码将不幸地导致 fatal error 。到目前为止,我还没有很好的解决方案。更多详情请引用Why I am getting Multithreading_Violation_AllThatIsLeftToUsIsHonor for this simplest NSAsynchronousFetchRequest use case?


请问newBackgroundContext + NSFetchRequestnewBackgroundContext + NSAsynchronousFetchRequest 有什么区别?

我应该如何选择一个而不是另一个?谢谢。

最佳答案

<强>1。关于 __Multithreading_Violation_AllThatIsLeftToUsIsHonor__ 异常:

本帖有详细讨论:
CoreData asynchronous fetch causes concurrency debugger error

一致认为这是 CoreData 中的一个错误。
有错误报告:https://openradar.appspot.com/30692722在撰写本文时 8 年后仍然开放。

<强>2。如何正确使用NSAsynchronousFetchRequest

该 API 于 2014 年推出,并在此 WWDC 视频中进行了讨论 225_sd_whats_new_in_core_data .
没有提到 NSAsynchronousFetchRequest 应该在主( View )上下文还是后台上下文中使用。

我在 GitHub 上使用 NSAsynchronousFetchRequest 查看了几个随机实现,并找到了主要和后台上下文的示例。

然而,在使用后台上下文时,您必须做的一件事是将获取执行包装在perform block ( documentation ) 中。
在您链接的文章和上面摘录的示例中,缺少此内容!
它应该是这样的:

privateManagedObjectContext.perform {
do {
try privateManagedObjectContext.execute(asynchronousFetchRequest)
} catch let error {
print("error trying to fetch saving objects:", error.localizedDescription)
}
}

同一篇文章还有另一个潜在的问题,所以要持保留态度:

DispatchQueue.main.async {
// here the objects in result (belongs to private context) are
// accessed on the main queue – the whole point is to *not* do that!
// one might get away with it because it is only read access to id
// but good luck debugging this...
let dogs: [Dog] = result.lazy
.flatMap { $0.objectID }
.flatMap { mainManagedObjectContext.object(with: $0) as? Dog }
// ...

我对NSAsynchronousFetchRequest的理解是,它最好从主上下文中使用,它的目的实际上是对你隐藏后台上下文业务。

所以:mainContext + NSAsynchronousFetchRequest

<强>3。我应该如何取舍?

在我看来,创建NSAsynchronousFetchRequest 的初衷是为了简化我们的异步核心数据获取。为此,您可以充分利用它来发挥自己的优势,尤其是当您需要处理进度和取消时。

但是我可能不会在我的项目中使用它,因为

  • 文档很少
  • 它没有得到很好的维护(一直以来都是开放的错误)
  • 它没有被很好地采用(例如流行和优秀的 CoreData 包装器 CoreStore 没有使用它)

最后一个想法 - 在开始异步获取之前,请确保您确实需要它。最好先优化查询、数据模型或批处理设置的性能。

关于ios - CoreData 中的异步读取 - 使用 newBackgroundContext + FetchRequest 与 newBackgroundContext + NSAsynchronousFetchRequest 的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70544438/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com