In my application, I have the ability to clear all data from the database. Once this operation completes, a bundled JSON is then parsed and then saved to the database (in order to return the database to the default state). The operation to parse and save this JSON works fine in any case except after clearing and recreating the persistant store, in which case I get 'NSInvalidArgumentException', reason: 'Object's persistent store is not reachable from this NSManagedObjectContext's coordinator'. This exception is thrown when trying to call mergeChangesFromContextDidSaveNotification on my main thread context after saving in a background context.
Recreating the store is performed on the main thread, where as parsing and saving always occurs on a background thread. Here is the getter for my managed object context to ensure thread-safeness:
- (NSManagedObjectContext *)managedObjectContext {
NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary];
NSManagedObjectContext *threadContext = threadDictionary[ckCoreDataThreadKey];
if (!threadContext) {
threadContext = [self newManagedObjectContext];
threadDictionary[ckCoreDataThreadKey] = threadContext;
}
return threadContext;
}
the newManagedObjectContext method gives all new instances the same NSPersistentStoreCoordinator object.
Here is the code used to clear the store (performed on main thread always):
[self.managedObjectContext lock];
[self.managedObjectContext reset]; //to drop pending changes
//delete the store from the current managedObjectContext
if ([[self.managedObjectContext persistentStoreCoordinator] removePersistentStore:[[[self.managedObjectContext persistentStoreCoordinator] persistentStores] lastObject] error:error]) {
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:error];
[[self.managedObjectContext persistentStoreCoordinator] addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:error]; //recreates the persistent store
[self addSkipBackupAttributeToItemAtURL:storeURL];
}
[self.managedObjectContext unlock];
The strange part is that this same code works fine in other projects, and there are no differences other than the content of the data. Any help is greatly appreciated!
A persistent store is a repository in which managed objects may be stored. You can think of a persistent store as a database data file where individual records each hold the last-saved values of a managed object. Core Data offers three native file types for a persistent store: binary, XML, and SQLite.
We can have only one Persistent Store Coordinator for each model.
To use Core Data in a multithreaded environment, ensure that: Managed object contexts are bound to the thread (queue) that they are associated with upon initialization. Managed objects retrieved from a context are bound to the same queue that the context is bound to.
Data persistence is the mechanism of storing any type of data to disk so that the same data can be retrieved without being altered when the user opens the app next time.
The "Object's persistent store is not reachable from this NSManagedObjectContext's coordinator"
This message means you tried to use a managed object that was loaded from the data store that you just removed. You removed the persistent store from the coordinator and deleted the store file, but you still have at least one NSManagedObject
that you loaded from that store. You can't use those objects any more, because if you do, you get this specific exception. Make sure you get rid of any existing managed objects before going nuclear on the Core Data stack in your second snippet.
As for why this works in a different app, most likely that app isn't holding on to stale managed objects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With