奇怪的核心数据行为

时间:2013-01-10 13:25:05

标签: objective-c core-data nsoperationqueue nsblockoperation

我使用NSBlockOperation执行一些工作,并且在此块中,持久存储会丢失其持久存储。

以下代码:

- (void) eraseCoreData_ManagedObjectsInArray:(NSArray *) arrayOfManagedObjectsToDelete usingManagedContext:(NSManagedObjectContext *) managedObjectContext
{
    NSLog(@"Managed object context is %@", managedObjectContext);
    NSLog(@"----->Persistent store of the deletion context has %d stores", [managedObjectContext.persistentStoreCoordinator.persistentStores count]);

    // add the operation to the queue with a block
    [self.coreDataDeletionQueue addOperationWithBlock:^{

    for (NSManagedObject *objectToDelete in arrayOfManagedObjectsToDelete) {
        [managedObjectContext deleteObject:objectToDelete];
    }

    NSLog(@"Managed object context in operation block is %@", managedObjectContext);
    NSLog(@"Persistence store coordinator in operation block is %@", managedObjectContext.persistentStoreCoordinator);
    NSLog(@"Persistent store of the deletion context in operation block has %d stores", [managedObjectContext.persistentStoreCoordinator.persistentStores count]);

    NSError *saveError = nil;
    if (![managedObjectContext save:&saveError]) {
        NSLog(@"Couldn't save Core-Data state for the deleted objects result: %@", [saveError localizedDescription]);
    }
    }];
}

记录下来:

托管对象上下文是< NSManagedObjectContext:0xa46ff10>

----->删除上下文的持久存储有1个存储

操作块中的托管对象上下文是< NSManagedObjectContext:0xa46ff10>

操作块中的持久性存储协调器是< NSPersistentStoreCoordinator:0xa1a45e0>

操作块中删除上下文的持久存储具有0个存储

  

* 由于未捕获的异常'NSInternalInconsistencyException'而终止应用,原因:'这   NSPersistentStoreCoordinator没有持久存储。这不可以   执行保存操作。'

我不确定为什么这个突然丢失的商店,可能是因为这是在我设置为使用内存存储的测试套件中运行而且内存未与此{{1}共享执行块?

1 个答案:

答案 0 :(得分:1)

我猜你是以错误的方式使用你的代码。

首先,每个线程必须拥有自己的上下文。因此,在块操作中,您需要创建一个新的上下文并在该块中使用它。

NSManagedObjectContext *blockContext = [[NSManagedObjectContext alloc] init];
[blockContext setPersistentStoreCoordinator:[managedObjectContext persistentStoreCoordinator]];

然后,如果您需要在上下文中共享对象,请使用NSManagedObjectID而不是NSManagedObject。 在创建该块之前保存主要上下文,或者您将只有临时ID。否则使用- (BOOL)obtainPermanentIDsForObjects:(NSArray *)objects error:(NSError **)error获取永久ID而不保存。

NSArray *objectIDs = [arrayOfManagedObjectsToDelete valueForKey:@"objectID"];

在块中使用- (NSManagedObject *)existingObjectWithID:(NSManagedObjectID *)objectID error:(NSError **)error通过blockContext检索您感兴趣的对象。

您的代码可能看起来像

NSArray *objectIDs = [arrayOfManagedObjectsToDelete valueForKey:@"objectID"];

// add the operation to the queue with a block
[self.coreDataDeletionQueue addOperationWithBlock:^{

    NSManagedObjectContext *blockContext = [[NSManagedObjectContext alloc] init];
    [blockContext setPersistentStoreCoordinator:[managedObjectContext persistentStoreCoordinator]];

    NSError* error = nil;
    for (NSManagedObject *objectID in objectIDs) {
        // some error handling here...
        NSManagedObject* objectToDelete = [existingObjectWithID:objectID error:&error];
        [blockContext deleteObject:objectToDelete];
    }

    if (![blockContext save:&error]) {
        NSLog(@"Couldn't save Core-Data state for the deleted objects result: %@", [error localizedDescription]);
    }
}];