2013-02-20 93 views
1

我想确保我的主线程永远不会阻塞,这就是为什么我想在后台执行我的核心数据保存。iOS背景保存在核心数据

我一直在阅读苹果文档以及这个链接(还有很多其他的,但是我发现这个非常有用):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个NSManagedObjectContexts,Apple文档明确指出每个线程只有1个NSManagedObjectContext。那么如何设置_managedObjectContext和_saveContext之间的父/子关系?我知道_saveContext需要在另一个线程中初始化,但我无法使这种方法工作。

+0

父上下文创建自己的线程,你不必创建一个。你的代码看起来不错,我看不到明显的错误。你是否检查过内部保存操作是否被实际执行?您也可以通过设置启动参数'-com.apple.CoreData.SQLDebug 1'来激活核心数据SQLite调试,然后您应该看看是否保存了某些内容。 – 2013-02-20 17:40:02

+0

我并不确定上下文是否创建了自己的线程,我猜想我对iOS 5之前发现的所有帖子感到困惑。错误是,我在代码中的某处传递了错误的上下文(有其他的后台队列以及提取),内部保存不是保存根上下文。现在在我的脑海里(和代码)全部整理出来,谢谢! ps:你可以发表这个答案,以便我可以接受它吗? – mmvie 2013-02-21 08:46:18

回答

0

(从评论)

所有“新”的管理对象上下文类型(NSMainQueueConcurrencyTypeNSPrivateQueueConcurrencyType)管理自己的线程,它是没有必要创建一个特殊的线程的上下文。唯一要记住的是始终使用performBlockperformBlockAndWait进行上下文中的操作。这确保操作在右侧队列和线程上执行。

所以你的代码是OK的。

(事实证明,错误是一个错误的情况下传递给你的储蓄常规,因此内保存未在顶级背景下完成的。)