Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.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
Objective c 单后台线程删除函数上的Core Data NSInternalInconsistency异常_Objective C_Core Data - Fatal编程技术网

Objective c 单后台线程删除函数上的Core Data NSInternalInconsistency异常

Objective c 单后台线程删除函数上的Core Data NSInternalInconsistency异常,objective-c,core-data,Objective C,Core Data,我的项目有一个数据库处理程序,它的功能之一是从数据库中删除几乎所有的记录。我在一个后台线程上执行实际的删除。有时我的代码工作正常,有时它会崩溃并出现NSInternalInconsistencyException。目前,三次尝试中有一次失败。为什么我会收到一个NSinternalinconsistency异常?我认为只有在多线程处理核心数据函数时才会发生这种情况。这是我的密码: //Database handler init. - (id)init { self = [super ini

我的项目有一个数据库处理程序,它的功能之一是从数据库中删除几乎所有的记录。我在一个后台线程上执行实际的删除。有时我的代码工作正常,有时它会崩溃并出现NSInternalInconsistencyException。目前,三次尝试中有一次失败。为什么我会收到一个NSinternalinconsistency异常?我认为只有在多线程处理核心数据函数时才会发生这种情况。这是我的密码:

//Database handler init.
- (id)init
{
    self = [super init];

    if(self) {
        self.appDelegate = [UIApplication sharedApplication].delegate;
        //getting the managedobjectcontext from appdelegate
        self.managedObjectContext = self.appDelegate.managedObjectContext;
        //background queue
        self.backgroundQueue = dispatch_queue_create("database.queue", NULL);
        status = 0;
    }

    return self;
}

//delete majority of the database entry
- (void) clearTables
    dispatch_async(self.backgroundQueue, ^(void) {

        NSError *error;

         //update this entity records.
        for(Entity1 *object in [self queryEntity:@"Entity1"]) {
            object.download_ymdhms = nil;
            [self.managedObjectContext save:nil];
        }

        [self.managedObjectContext save:&error];
        NSLog(@"error1: %@", [error localizedDescription]);

        //Delete the other entities data.   
        for(Entity2 *object in [self queryEntity:@"Entity2"]) {
            [self.managedObjectContext deleteObject:object];
        }
        [self.managedObjectContext save:&error];
        NSLog(@"error2: %@", [error localizedDescription]);

        for(Entity3 *object in [self queryEntity:@"Entity3"]) {
            [self.managedObjectContext deleteObject:object];
        }

        ...

        for(Entity10 *object in [self queryEntity:@"Entity10"]) {
            [self.managedObjectContext deleteObject:object];
        }

        [self.managedObjectContext save:&error];
        NSLog(@"error3: %@", [error localizedDescription]);

        //notify deletion complete
        [[NSNotificationCenter defaultCenter] postNotificationName:@"database.queue.delete.done" object:nil];
    });
}

//get all the objects in an entity.
- (NSArray *) queryEntity: (NSString *)entity {
    return [self queryEntity:entity withPredicate:nil withLimit:0 orderBy:nil];
}

...

//general query
- (NSArray *) queryEntity: (NSString *)entity withPredicate: (NSString *)predicate withLimit: (int)limit orderBy: (NSString *)order
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:[NSEntityDescription entityForName:entity inManagedObjectContext:self.managedObjectContext]];

    if(predicate.length > 0) {
        [fetchRequest setPredicate:[NSPredicate predicateWithFormat: predicate]];
    }

    if(limit > 0) {
        [fetchRequest setFetchLimit:limit];
    }

    if(order.length > 0) {
        [fetchRequest setSortDescriptors: @[[[NSSortDescriptor alloc] initWithKey:order ascending:YES]]];
    }

    NSError *error;
    NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];

    return results;
}   
这是我有时会遇到的错误:

CoreData: error: Serious application error.  Exception was caught during Core Data change processing.  This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification.  statement is still active with userInfo (null)
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'statement is still active'

编辑:添加代码注释以使其更具可读性。

我认为您不能只在后台线程上调用主上下文。如果要在后台线程上使用上下文,必须在后台线程上创建上下文。尝试在主线程上运行它,看看是否有错误。如果我在主线程中运行所有内容,UI显示将冻结。删除所有这些数据需要15-30秒。当然,我知道如果你这样做,UI会冻结,但你不应该得到任何错误,尽管这对生产没有好处。要正确修复它,请在后台线程上创建另一个managedObjectContext,然后使用该MOC在同一线程上执行删除。不能使用主线程managedObjectContext。