gpt4 book ai didi

multithreading - Core Data,在后台线程中修改 NSManagedObject

转载 作者:行者123 更新时间:2023-12-03 17:50:36 25 4
gpt4 key购买 nike

我想知道是否可以在后台线程中修改已在主线程中加载的 NSManagedObject - 然后将上下文保存回主线程中。我知道我无法从后台线程保存上下文。

这主要是虚拟代码(Swift),但它显示了我如何在后台线程中更改对象的属性并将上下文保存回主线程中:

var myObject = coreDataHelper.loadSomeObjectFromDB()
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
doSomeHeavyLifting()
myObject.someProperty = "foo"
dispatch_async(dispatch_get_main_queue()) {
coreDataHelper.saveManagedObjectContext()
}
}

我这么问是因为我的应用程序偶尔会发生与核心数据相关的随机崩溃,我想知道这是否是由于我的上述工作流程造成的。

这是异常(exception):

CoreData: error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. -[__NSCFSet addObject:]: attempt to insert nil with userInfo (null)

只是我自己没有定义任何NSManagedObjectContextObjectsDidChangeNotification

因此,如果这是崩溃的原因,是否就像将行 myObject.someProperty = "foo" 移动到主队列中一样简单,如下所示?:

var myObject = coreDataHelper.loadSomeObjectFromDB()
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
doSomeHeavyLifting()
dispatch_async(dispatch_get_main_queue()) {
myObject.someProperty = "foo" //moved this line into main thread
coreDataHelper.saveManagedObjectContext()
}
}

最佳答案

如注释中所述(以一种或另一种方式),您无法将 NSManagedObject 实例从一个线程传递到另一个线程。但是,您可以传递线程安全的NSManagedObjectID。然后,您可以使用 context.objectWithID(objectID) 在不同线程中检索对象。

根据我们使用 Core Data 的经验,将 MainQueueConcurrencyTypePrivateQueueConcurrencyType 类型的托管对象上下文与 performBlockperformBlockAndWait 一起使用> 比使用 ConfinementConcurrencyType 对我们来说效果更好(默认)。因此,代码看起来类似于:

// in main thread
var myObject = getObjectInMainThread()
let objectID = myObject.objectID
let privateContext = coreDataHelper.createPrivateContext() // creates a PrivateConcurrencyType context and returns

privateContext.performBlock {
var object = privateContext.objectWithID(objectID)
doSomeHeavyLiftingWithObject()
// coreDataHelper should be listening to
// NSManagedObjectContextDidSaveNotification and merge changes to main
privateContext.save(nil)
dispatch_async(dispatch_get_main_queue()) {
// because changes are merged by listening to context "did save"
// notification, the update should already be reflected in the
// previously retrieved object
myObject.someProperty = "foo" // moved this line into main thread
coreDataHelper.saveManagedObjectContext()
}
}

关于multithreading - Core Data,在后台线程中修改 NSManagedObject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28623016/

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