【发布时间】:2015-02-20 06:39:10
【问题描述】:
我想知道是否可以在主线程中加载的后台线程中修改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()
}
}
我之所以问,是因为我的应用程序偶尔会出现与核心数据相关的随机崩溃,并且想知道这是否可能是由于我的上述工作流程造成的。
这是个例外:
CoreData:错误:严重的应用程序错误。异常被捕获 在核心数据更改处理期间。这通常是一个错误 NSManagedObjectContextObjectsDidChangeNotification 的观察者。 -[__NSCFSet addObject:]: 尝试用 userInfo (null) 插入 nil
只是我自己没有定义任何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()
}
}
【问题讨论】:
-
这取决于上下文,如果您的 NSManagedContext 是在主线程上创建的,那么您只能在主线程上执行操作。
-
是的,上下文当然是在主线程上创建的。那就是我加载对象的地方。所以不仅不能在后台线程中保存上下文,而且不能在后台修改对象然后将上下文保存在主线程中以将这些更改保存到磁盘?
-
好吧,这也不是,您只能在同一个线程中操作 coredata 对象。尽管在 iOS8 中,Apple 已经在 Coredata 中发布了异步获取。 code.tutsplus.com/tutorials/…
-
谢谢。这就是我所害怕的。这对我来说意味着更多的重构。我用另一种方法更新了这个问题。理论上可以吗,因为对象随后会在主线程中被操作回?
-
是的,应该可以。
标签: multithreading cocoa core-data nsmanagedobject nsmanagedobjectcontext