我正在使用 CoreData,当我尝试在容器的 PerformBackgroundTask 函数中保存上下文时遇到问题。
我同时从多个地方调用此电话。我的理解是,每次线程都会不同,导致尝试保存到持久存储时出现问题。
我曾考虑使用 childContext 和其他方法,直到我遇到以下文章:
https://blog.five.agency/how-to-import-a-large-data-set-using-core-data-6c248a503148
文章中的coreData堆栈如下:
final class DataCoordinator {
//MARK: - singleton
static let sharedInstance = DataCoordinator()
//MARK: - init
public var container : NSPersistentContainer
private init() {
container = NSPersistentContainer(name: "Model")
container.loadPersistentStores(completionHandler: { (_, error) in
if let error = error {
fatalError("Unresolved error \(error)")
}
})
}
//MARK: - perform methods
static func performBackgroundTask(_ block: @escaping (NSManagedObjectContext) -> Void) {
DataCoordinator.sharedInstance.container.performBackgroundTask(block)
}
static func performViewTask(_ block: @escaping (NSManagedObjectContext) -> Void) {
block(DataCoordinator.sharedInstance.container.viewContext)
}
}
我的问题是使用这种方法,静态函数performBackgroundTask是否会克服这个问题,并始终在同一队列上为我提供相同的背景上下文,或者这与我之前每次使用container.performBackgroundTask所做的没有什么不同?
想知道如何在同一个队列中同时从多个位置进行保存?
最佳答案
嗨,第一件事是它与队列无关,NSManagedObjectContext
在不同的队列上运行,就像 viewContext 在主队列上运行一样。因此,在您的情况下,我认为您想使用相同的 NSManagedObjectContext
从不同的地方保存?如果是这种情况,您可以获取一个 newBackgroundContext 并保存它的引用,并使用此上下文从所有位置保存您的任务。使用下面的 NSPercientContainer
方法来获取后台上下文。
func newBackgroundContext() -> NSManagedObjectContext
如果我对您的问题的理解是错误的,请告诉我更多信息,以便我可以为您提供其他解决方案。
同样,您提到的教程中的以下方法不适合您
static func performBackgroundTask(_ block: @escaping (NSManagedObjectContext) -> Void) {
DataCoordinator.sharedInstance().container.performBackgroundTask(block)
}
因为performBackgroundTask
总是创建一个新的上下文。苹果文档说:
每次调用此方法时,持久性容器都会创建一个新的 NSManagedObjectContext
,并将 concurrencyType 设置为 NSManagedObjectContextConcurrencyType.privateQueueConcurrencyType。
然后,持久性容器会执行传入的 block 在上下文的私有(private)队列上新创建的上下文。
关于ios - CoreData执行后台任务冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51463542/