同时在CoreData中工作

时间:2013-03-12 14:03:35

标签: objective-c xcode core-data nsmanagedobjectcontext

首先,对不起,如果我的英语不完美,我不是英语本地人;)!

我正在开发一个从iCal检索EKEvent并将它们添加到我的应用程序的应用程序。

申请的目的是日历,所以:

用户从他想要的日历中检索iCal的EKEvent。

EKEvent保存在名为“Event”的实体中。

用户可以编辑,添加,删除应用程序中的事件 - 也将在iCal中修改EKEvent关联。

问题:当用户在iCal中修改内容时,必须将其修改为我的应用程序,因此我找到的唯一方法是从iCal中检索所有EKEvent - 当应用程序变为活动状态时 - 并将其复制到名为“的BackUp实体”中EventBackup”。当来自iCal的所有EKEvent都被很好地检索并保存到“EventBackup”实体中时,我将该实体复制到我的主要实体“事件”中。

我正在与

异步完成
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void) { });

但是我必须继续使用我的应用程序 - 所以从CoreData检索Event * - 当我正在做EventBackup ...问题如果我正在处理CoreData,我的应用程序崩溃。

你能以这种方式提供帮助,或者向我提出与我正在做的事情不同的事情。

非常感谢帮助我!

2 个答案:

答案 0 :(得分:1)

您应该查看NSManagedObjectContext的performBlock:方法。具体来说,您应该创建一个子上下文,在后台线程中对其进行更改,然后侦听保存通知以将其合并到父上下文中。

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

NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[childContext setParentContext:self.managedObjectContext];
[childContext performBlock:^{

    //Do everything here...

    NSError *error = nil;
    [context save:&error];
    if (error) {
        NSLog(@"Error saving child context:%@", error.localizedDescription);
    }

 }];

侦听要保存的子上下文,然后保存主上下文。

 - (void)managedObjectContextDidSave:(NSNotification *)notification
 {
    if ([notification object] != self.managedObjectContext) {
       dispatch_sync(dispatch_get_main_queue(), ^{
         [self.managedObjectContext save:nil];
      });
    }
  }

答案 1 :(得分:0)

要更清楚我正在做什么 - 使用你的代码。

块中的方法正在处理childContext的NSManagedObjectContext

我在AppDelegate,

- (void)methodToBeCalledEveryTimeTheAppBecomeActive
{

    NSManagedObjectContext *contextParent = [[LavigneCoreData defaultManager] managedObjectContext];


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

    childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [childContext setParentContext:contextParent];
    [childContext performBlock:^{

        [self copySpecialsEvents];
        [self clearBackUpEntity];
        [self getCalendarWhichHasBeenSelected];
        [self copyNotesIntoBackUpEntity];
        [self clearEntityEvent];
        [self deepCopyFromBackUpEntityToEntity];

        NSError *error = nil;
        [contextParent save:&error];
        if (error) {
            NSLog(@"Error saving child context:%@", error.localizedDescription);
        }
    }];
}

我收到了错误:[childContext setParentContext:contextParent];

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Parent NSManagedObjectContext must use either NSPrivateQueueConcurrencyType or NSMainQueueConcurrencyType.'

编辑:

我通过更改

修复了此错误
_managedObjectContext = [[NSManagedObjectContext alloc] init];

_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];