0

首先,对不起,如果我的英语不完美,我不是一个以英语为母语的人 ;) !

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

该应用程序的目的是日历,因此:

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

EKEvent 被保存到一个名为“Event”的实体中。

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

问题:当用户在 iCal 中修改某些内容时,必须将其修改到我的应用程序中,所以我发现的唯一方法是从 iCal 检索所有 EKEvent - 当应用程序变为活动时 - 并将其复制到名为“EventBackup”的备份实体中。当 iCal 中的所有 EKEvent 都被很好地检索并保存到“EventBackup”实体中时,我将该实体复制到我的主实体“Event”中。

我在异步中成功地做到了

  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void) { });

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

你能帮忙吗,或者向我提出一些与我正在做的不同的事情。

非常感谢你帮助我!

4

2 回答 2

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];
      });
    }
  }
于 2013-03-12T21:18:32.690 回答
0

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

块中的方法正在处理childContextNSManagedObjectContext

我在 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];
于 2013-03-13T10:03:13.620 回答