0

我遇到了与我的核心数据实现和线程相关的问题。它在 iOS 7 上运行良好,但我无法在 iOS 6 上正确刷新主要上下文。

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

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

我知道 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 采取不同的方法,我猜......

4

1 回答 1

0

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

  • 207 - Core Data 中的新增功能(从第 145 张幻灯片开始)。
  • 211 - 核心数据性能(从幻灯片编号 91 开始),
于 2013-10-24T10:04:19.840 回答