Reputation: 29906
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?
Upvotes: 0
Views: 263
Reputation: 33428
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]);
}
}];
Upvotes: 1