iOS 后台保存在 Core Data 中
Posted
技术标签:
【中文标题】iOS 后台保存在 Core Data 中【英文标题】:iOS background save in Core Data 【发布时间】:2013-02-20 09:58:09 【问题描述】:我想确保我的主线程永远不会阻塞,这就是为什么我想在后台保存我的核心数据。
我一直在阅读 Apple 文档以及此链接(以及许多其他文档,但我发现这个非常有用):http://www.cocoanetics.com/2012/07/multi-context-coredata/,尽管我无法正确构建架构。
在我的 AppDelegate.m 中:
- (NSManagedObjectContext *)managedObjectContext
if (_managedObjectContext != nil)
return _managedObjectContext;
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil)
_saveContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_saveContext setPersistentStoreCoordinator:coordinator];
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_managedObjectContext setParentContext:_saveContext];
return _managedObjectContext;
然后为了保存,我会这样做:
// var 'context' is the context coming from method managedObjectContext
// this code is in the same thread 'context' is created in (the main thread)
NSError *error = nil;
if ([context save:&error])
[context.parentContext performBlock:^
NSError *err = nil;
if(![context.parentContext save:&err])
NSLog(@"Error while saving context to the persistent store");
];
else
// handle error
这是我通过阅读我之前提供的链接所得到的。保存不起作用,一旦应用程序关闭并重新打开,对任何托管对象所做的更改都将消失:它们从未保存到持久存储中。
我猜是有道理的,因为我在 1 个线程中创建了 2 个 NSManagedObjectContext,Apple 文档明确声明每个线程只有 1 个 NSManagedObjectContext。那么如何设置 _managedObjectContext 和 _saveContext 之间的父/子关系呢?我知道 _saveContext 需要在另一个线程中初始化,但我无法使用这种方法。
【问题讨论】:
父上下文创建自己的线程,你不必创建一个。您的代码看起来不错,我看不到明显的错误。您是否检查过内部保存操作是否实际执行?您还可以通过设置启动参数-com.apple.CoreData.SQLDebug 1
来激活 Core Data SQLite 调试,然后您应该查看是否保存了某些内容。
我不确定上下文创建了自己的线程,我猜我对我发现的所有在 ios 5 之前写的帖子感到困惑。错误是我在某些时候传递了错误的上下文在我的代码中(还有一些其他后台队列用于获取)并且内部保存不是根上下文的保存。现在在我的脑海中(和代码)都整理好了,谢谢! ps:你能把这个作为答案发给我吗?
【参考方案1】:
(来自 cmets)
所有“新”托管对象上下文类型(NSMainQueueConcurrencyType
、NSPrivateQueueConcurrencyType
)都管理自己的线程,无需在特殊线程上创建上下文。唯一要记住的是始终使用performBlock
或performBlockAndWait
进行上下文中的操作。这样可以确保操作在正确的队列和线程上执行。
所以你的代码没问题。
(事实证明,错误是错误的上下文被传递给您的保存例程,因此内部保存没有在***上下文中完成。)
【讨论】:
以上是关于iOS 后台保存在 Core Data 中的主要内容,如果未能解决你的问题,请参考以下文章
Core Data,在后台线程中修改 NSManagedObject