I'm banging my head against the wall here, I'm using Core Data for a SQLLite DB, and I am able to successfully save to the database (I've checked the contents in an offline SQLLite browser), but after saving the first query I attempt to run comes back with the error seen below, and I can't find any helpful information on the internet relating to this specific error:
Core Data: error: -executeRequest: encountered exception = The database appears corrupt. (invalid primary key) with userInfo = { NSFilePath = "/Users/user/Library/Application Support/iPhone Simulator/7.0.3/Documents/db.sqlite";
The question here, is what causes this error, as I can't find any information relating to it.
For a little background, this is my setup, please assume I've got good reasons for the design that has been made and don't provide an answer of "Change your design" unless you can see something fundamentally broken with the pattern itself.
I have 3 Managed object contexts, all of them are NSPrivateQueueConcurrencyType, the first (A) is attached to the Persistent Store Coordinator, the second (B) has A set as its parent context, and the third (C) has B set as it's parent context -- A chain. The reason for this is that C is a writable context, fetching data from a network source and synchronizing it and saving it, B is a context shared by the UI elements, and I want it to be responsive, finally A is a background context designed to offload any delays for saving to disk off Context B & C
PSC <-- A <-- B <-- C
If I take out the last step (Saving A to PSC) then the application runs great, keeping everything in memory and querying against the in memory contexts. The crash only occurs after I add the save step back in, and only on the first query run against the DB after that save. Both my Save's and my fetch execution are wrapped in performBlock:
Here is the last save:
- (void)deepSave
{
// Save to the Save Context which happens in memory, so the actual write to disk operation occurs on background thread
// Expects to be called with performBlock
NSError *error = nil;
[super save:&error];
NSAssert(!error, error.localizedDescription);
// Trigger the save context to save to disk, operation will be queued and free up read only context
NSManagedObjectContext *saveContext = self.parentContext;
[saveContext performBlock:^{
NSError *error = nil;
[saveContext save:&error];
NSAssert(!error, error.localizedDescription);
}];
}
And here is the execute stack (on NSManagedObjectContext Queue thread)
#0 0x0079588a in objc_exception_throw ()
#1 0x079d98e7 in -[NSSQLiteConnection handleCorruptedDB:] ()
#2 0x078d9b8d in -[NSSQLiteConnection fetchResultSet:usingFetchPlan:] ()
#3 0x078e24a5 in newFetchedRowsForFetchPlan_MT ()
#4 0x078cd48e in -[NSSQLCore newRowsForFetchPlan:] ()
#5 0x078cca8d in -[NSSQLCore objectsForFetchRequest:inContext:] ()
#6 0x078cc53f in -[NSSQLCore executeRequest:withContext:error:] ()
#7 0x078cbf62 in -[NSPersistentStoreCoordinator executeRequest:withContext:error:] ()
#8 0x078c96c6 in -[NSManagedObjectContext executeFetchRequest:error:] ()
#9 0x0791e526 in -[NSManagedObjectContext(_NestedContextSupport) _parentObjectsForFetchRequest:inContext:error:] ()
#10 0x0799c1f4 in __82-[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]_block_invoke ()
#11 0x0791e321 in internalBlockToNSManagedObjectContextPerform ()
#12 0x013c34b0 in _dispatch_client_callout ()
#13 0x013b0778 in _dispatch_barrier_sync_f_invoke ()
#14 0x013b0422 in dispatch_barrier_sync_f ()
#15 0x0791e2a2 in _perform ()
#16 0x0791e14e in -[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:] ()
#17 0x078c96c6 in -[NSManagedObjectContext executeFetchRequest:error:] ()
#18 0x0791e526 in -[NSManagedObjectContext(_NestedContextSupport) _parentObjectsForFetchRequest:inContext:error:] ()
#19 0x0799c1f4 in __82-[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]_block_invoke ()
#20 0x0791e321 in internalBlockToNSManagedObjectContextPerform ()
#21 0x013c34b0 in _dispatch_client_callout ()
#22 0x013b0778 in _dispatch_barrier_sync_f_invoke ()
#23 0x013b0422 in dispatch_barrier_sync_f ()
#24 0x0791e2a2 in _perform ()
#25 0x0791e14e in -[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:] ()
#26 0x078c96c6 in -[NSManagedObjectContext executeFetchRequest:error:] ()