Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 启动后,在后台删除不起作用_Iphone_Ios_Core Data_Nsfetchedresultscontroller_Grand Central Dispatch - Fatal编程技术网

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

Iphone 启动后,在后台删除不起作用,iphone,ios,core-data,nsfetchedresultscontroller,grand-central-dispatch,Iphone,Ios,Core Data,Nsfetchedresultscontroller,Grand Central Dispatch,我正在尝试创建一些方法,使在后台执行核心数据变得更容易。我正在做的是: 使用NSOperationQueue的-addOperationWithBlock:创建后台线程 在后台线程中,使用与主线程上的上下文相同的persistentStoreCoordinator创建一个NSManagedObjectContext,并将undoManager设置为nil 将观察者添加到默认通知中心,以侦听NSManagedObjectContextDidSaveNotification通知,并按如下方式处理它

我正在尝试创建一些方法,使在后台执行核心数据变得更容易。我正在做的是:

  • 使用
    NSOperationQueue
    -addOperationWithBlock:
    创建后台线程
  • 在后台线程中,使用与主线程上的上下文相同的
    persistentStoreCoordinator
    创建一个
    NSManagedObjectContext
    ,并将
    undoManager
    设置为
    nil
  • 将观察者添加到默认通知中心,以侦听
    NSManagedObjectContextDidSaveNotification
    通知,并按如下方式处理它们:

    - (void)mergeChanges:(NSNotification *)notification
    {
        dispatch_sync(dispatch_get_main_queue(), ^{
            [_mainContext mergeChangesFromContextDidSaveNotification:notification];
        });
    }
    
    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];
            }
        }
        }];
    
  • 执行一个传入的块,它执行所有核心数据。它会定期在后台上下文中调用
    save:

  • 完成所有操作后,将观察员从通知中心移除
下面可以找到所描述的方法

一切正常。我可以传入添加数据、更新数据或删除数据的块但是:当我用一些数据关闭应用程序,重新打开它,然后尝试在后台删除数据时,出现以下错误:

CoreData:错误:严重的应用程序错误。发现了一个异常 在调用时从NSFetchedResultsController的委托 -controllerDidChangeContent:。CoreData无法实现[…]的故障

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

有没有关于如何解决这个问题的建议


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

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
的实现:

+ (NSOperationQueue *)sharedQueue
{
    static dispatch_once_t predicate = 0;

    __strong static NSOperationQueue *_sharedQueue = nil;

    dispatch_once(&predicate, ^{
        _sharedQueue = [[NSOperationQueue alloc] init];
        [_sharedQueue setMaxConcurrentOperationCount:1];
    });

    return _sharedQueue;
}

+ (void)addOperationWithBlock:(void (^)(void))block
{
    [[FJSharedOperationQueue sharedQueue] addOperationWithBlock:block];
}

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

- (void)mergeChanges:(NSNotification *)notification
{
    dispatch_sync(dispatch_get_main_queue(), ^{
        [_mainContext mergeChangesFromContextDidSaveNotification:notification];
    });
}
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];
        }
    }
    }];
FJCoreDataHelper*helper=[[FJCoreDataHelper alloc]initUsingMainManagedObjectContext:[self-mainContext]];
[helper performBlockInBackground:^(NSManagedObjectContext*backgroundContext){
//[在这里取对象…]
//删除:
const int ksavestreshold=50;
对于(int card=0,count=[allCards count];card
要修复它,我只需在保存背景上下文后保存主上下文:

[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];
        }
    }
    }];
[helper performBlockInBackground:^(NSManagedObjectContext*backgroundContext){
//[在这里取对象…]
//删除:
const int ksavestreshold=50;
对于(int card=0,count=[allCards count];card
如果我只保存背景上下文,它就会崩溃。如果我先保存主上下文,它也会崩溃。我觉得这很奇怪,因为我认为将背景上下文合并到主上下文中也可以保存主上下文