启动后在后台删除不起作用

时间:2012-01-29 14:50:26

标签: iphone ios core-data nsfetchedresultscontroller grand-central-dispatch

我正在尝试创建一些方法,以便更容易在后台执行Core Data。我正在做的是:

  • 使用NSOperationQueue的{​​{1}}创建后台主题
  • 在后台主题中,使用与主线程上下文相同的-addOperationWithBlock:创建NSManagedObjectContext,并将persistentStoreCoordinator设置为undoManager
  • 将观察者添加到默认通知中心以收听nil通知并按照以下方式处理:

    NSManagedObjectContextDidSaveNotification
  • 执行传入的块并执行所有Core Data的操作。它会定期在背景上下文中调用- (void)mergeChanges:(NSNotification *)notification { dispatch_sync(dispatch_get_main_queue(), ^{ [_mainContext mergeChangesFromContextDidSaveNotification:notification]; }); }

  • 完成所有操作后,从通知中心删除观察者

所描述的方法可以在下面找到。

一切都按预期工作。我可以传入添加数据,更新数据或删除数据的块。 但是:当我使用某些数据关闭应用时出现以下错误,重新打开它然后尝试在后台删除数据:

  

CoreData:错误:严重的应用程序错误。抓住了一个例外   在调用期间来自NSFetchedResultsController的委托   -controllerDidChangeContent :. CoreData无法解决[...]

的错误

从错误中可以明显看出,我使用save:来显示数据。控制器的缓存设置为NSFetchedResultsController

有关如何解决此问题的任何建议吗?


这是相关代码。请注意,我正在使用ARC。

nil的定义如下:

FJCoreDataBackgroundBlock

在后台执行一堆核心数据的方法

typedef void(^FJCoreDataBackgroundBlock)(NSManagedObjectContext *backgroundContext);

- (void)performBlockInBackground:(FJCoreDataBackgroundBlock)block { [FJSharedOperationQueue addOperationWithBlock:^{ self.managedObjectContext = [[NSManagedObjectContext alloc] init]; [_managedObjectContext setUndoManager:nil]; [_managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator]; [self setupNotificationCenterObserverForContext:_managedObjectContext]; FJCoreDataBackgroundBlock backgroundBlock = [block copy]; backgroundBlock(self.managedObjectContext); [self saveBackgroundContext]; [self saveMainContext]; [self removeNotificationCenterObserver]; }]; } 的实施:

FJSharedOperationQueue

1 个答案:

答案 0 :(得分:0)

现在这很奇怪:我在块中删除了删除对象的代码行。在它看起来像这样之前:

FJCoreDataHelper *helper = [[FJCoreDataHelper alloc] initUsingMainManagedObjectContext:[self mainContext]];

[helper performBlockInBackground:^(NSManagedObjectContext *backgroundContext) {

    // [Fetch objets here...]

    // Delete:

    const int kSaveThreshold = 50;
    for (int card = 0, count = [allCards count]; card < count; card++)
    {
        [backgroundContext deleteObject:[allCards objectAtIndex:card]];

        if (card % kSaveThreshold == 0)
        {
            [helper saveBackgroundContext];
        }
    }
    }];

要修复它,我只需在保存背景上下文后保存主要上下文:

[helper performBlockInBackground:^(NSManagedObjectContext *backgroundContext) {

    // [Fetch objets here...]

    // Delete:

    const int kSaveThreshold = 50;
    for (int card = 0, count = [allCards count]; card < count; card++)
    {
        [backgroundContext deleteObject:[allCards objectAtIndex:card]];

        if (card % kSaveThreshold == 0)
        {
            [helper saveBackgroundContext];
            [helper saveMainContext];
        }
    }
    }];

如果我只保存背景上下文,它会崩溃。如果我先保存主要上下文,它也会崩溃。我发现这很奇怪,因为我认为将背景上下文合并到主要上下文中也会保存主要上下文......