CoreData线程。 iOS 6 vs 7

时间:2013-10-24 09:31:03

标签: ios objective-c multithreading core-data

我遇到了与核心数据实施和线程相关的问题。它在iOS 7上工作正常但我无法在iOS 6上正确刷新主要上下文。

我有两个NSPersistentStoreCoordinators指向同一个数据库文件。然后我有一个主要的上下文和一个背景上下文。所有新的子环境都是背景环境的子女。

当我在6上的后台线程中更新子上下文中的项目时,它们永远不会合并到主上下文,直到我重新启动应用程序并且主上下文从商店中获取它们。在ios7上,这一切都运行正常。如何确保主上下文正确刷新合并而不会出错并重新加载db?

我知道默认情况下iOS 7启用了异步sql访问,但是我已经在6上完成了:

  NSSQLitePragmasOption : @{@"journal_mode" : @"WAL"} 

以下是我的上下文的设置方式:

    self.mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [self.mainManagedObjectContext setPersistentStoreCoordinator:self.mainPersistentStoreCoordinator];
    [self.mainManagedObjectContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
    [self.mainManagedObjectContext setUndoManager:nil];
    self.backgroundParentContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [self.backgroundParentContext setPersistentStoreCoordinator:self.backgroundPersistentStoreCoordinator];
    [self.backgroundParentContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
    [self.backgroundParentContext setUndoManager:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(backgroundContextDidSave:) name:NSManagedObjectContextDidSaveNotification object:self.backgroundParentContext];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mainContextDidSave:) name:NSManagedObjectContextDidSaveNotification object:self.mainManagedObjectContext];

以下是我创建子上下文的方法:

- (NSManagedObjectContext *)newChildManagedObjectContext
{
     NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] 
                                 initWithConcurrencyType:NSPrivateQueueConcurrencyType];

     [childContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];

     [childContext setParentContext:self.backgroundParentContext];

     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextDidSave:)
                                name:NSManagedObjectContextDidSaveNotification object:childContext];
     [childContext setUndoManager:nil];
     return childContext;
}

以下是通知方法:

- (void)mainContextDidSave:(NSNotification *)notification
{
    __block NSNotification *strongNotification = notification;
    [self.backgroundParentContext performBlockAndWait:^{
    [self.backgroundParentContext mergeChangesFromContextDidSaveNotification:strongNotification];
    }];
 }

 - (void)backgroundContextDidSave:(NSNotification *)notification
 {
    [self.mainManagedObjectContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:NO];
 }

 - (void)managedObjectContextDidSave:(NSNotification *)notification
 {
      [self.backgroundParentContext performBlockAndWait:^{
      NSError *error = nil;
      if (![self.backgroundParentContext save:&error]) {
             DNSLog(@"error saving context: %@", error); 
       }
   }];
 }

更新:

好吧看起来这只是永远不会继续工作6.根据文档,他们已经改变了相当大约7的上下文。所以我将不得不采取不同的方法6我猜...

1 个答案:

答案 0 :(得分:0)

我在iOS 6上没有使用过两个NSPersistentStoreCoordinators,但在WWDC期间明确提到了来自不同商店协调员的上下文之间的合并更改,因此我认为它在iOS 7中已更改。请参阅以下会话:

  • 207 - Core核心数据有什么新功能(从幻灯片编号145开始)。
  • 211 - 核心数据性能(从幻灯片编号91开始),