Question

I perform some work using an NSBlockOperation and inside this block the persistent store loses its persistent stores.

the following code:

- (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]);
    }
    }];
}

logs this out:

Managed object context is < NSManagedObjectContext: 0xa46ff10 >

----->Persistent store of the deletion context has 1 stores

Managed object context in operation block is < NSManagedObjectContext: 0xa46ff10 >

Persistence store coordinator in operation block is < NSPersistentStoreCoordinator: 0xa1a45e0 >

Persistent store of the deletion context in operation block has 0 stores

* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This NSPersistentStoreCoordinator has no persistent stores. It cannot perform a save operation.'

I am not sure why this sudden lose of stores, could it be due to the fact that this is running in a test suite that I set to use an in memory store and the memory is not shared with this NSOperationQueue that executes the blocks?

Était-ce utile?

La solution

My guess you are using your code in the wrong manner.

First, each thread must have its own context. So, inside the block operation you need to create a new context and use it within that block.

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

Then, if you need to share objects within contexts, use NSManagedObjectID and not NSManagedObject. Before creating that block save the main context or you will have only temporary ids. Otherwise use - (BOOL)obtainPermanentIDsForObjects:(NSArray *)objects error:(NSError **)error to obtain permanent ids without saving.

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

Within the block use - (NSManagedObject *)existingObjectWithID:(NSManagedObjectID *)objectID error:(NSError **)error to retrieve the object you are interested in through blockContext.

Your code could look like

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]);
    }
}];
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top