免责声明
Daniel Dickison响应是正确的答案。我只是在这里提供一些额外的细节和解释,因为其中一些步骤并非微不足道。
使用2个不同的管理对象上下文是做
UI线程MOC正确的事情:
lazy var mainQueuemanagedObjectContext: NSManagedObjectContext = {
let coordinator = self.persistentStoreCoordinator
var managedObjectContext = NSManagedObjectContext(
concurrencyType: .MainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
传输,下载,背景商务部:
lazy var transportManagedObjectContext:NSManagedObjectContext = {
let coordinator = CoreDataStack.sharedInstance.persistentStoreCoordinator
let managedObjectContext = NSManagedObjectContext(
concurrencyType: .PrivateQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
使用后台MOC进行后台操作:
(如新的数据被下载和保存)
transportManagedObjectContext.performBlockAndWait({() -> Void in
// ...add, change, delete objects, then save
try transportManagedObjectContext.save()
})
适用于背景管理对象上下文Daniel Dickison'响应,按照所述Apple documentation:
// Broadcast NSManagedObjectContextDidSaveNotification
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: "mocDidSaveNotification:",
name: NSManagedObjectContextDidSaveNotification,
object: self.transportManagedObjectContext)
func mocDidSaveNotification(notification:NSNotification)
{
mainQueuemanagedObjectContext.performSelectorOnMainThread(
"mergeChangesFromContextDidSaveNotification:",
withObject: notification,
waitUntilDone: true)
}
注:我通常更喜欢使用performBlockAndWait()
和waitUntilDone: true
,除非我肯定知道不等待不会造成竞赛状况。如果您决定不是等待,我邀请您彻底测试您的应用程序。我冒昧地让后台线程等待UI,但是反过来永远不会。
从UI线程
NSFetchedResultsController
必须使用MainQueueConcurrencyType
管理对象上下文听。
let fetchedResultsController = NSFetchedResultsController(
fetchRequest: fetchRequest,
managedObjectContext: mainQueuemanagedObjectContext,
sectionNameKeyPath: "yourKey",
cacheName: nil)
你NSFetchedResultsController
从后台管理对象上下文中解脱出来,并会收到controllerWillChangeContent
,didChangeObject
等后的合并已经完成。
感谢您的回答,我结束了您的解决方案。令我困惑的是,关于Apple文档,从后台线程调用mergeChangesFromContextDidSaveNotification(该方法设计为线程安全)是合法的。所以我想,Core Data本身会以某种方式神奇地管理在正确线程上传递给我的NSFetchedResultsController的更改。 – Martin
我同意在这一点上文档混淆。它说你可以传递一个在另一个线程上发布的通知,但它并没有说它是线程安全的,或者你可以从另一个线程调用这个方法,所以这在技术上并不正确。我建议在文档页面上提交注释:http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObjectContext_Class/NSManagedObjectContext.html –