Master data - lock when deleting persistent storage

Is there a safe way to remove persistent storage (and create a new one) in an application where other threads use the NSManagedObjectContext associated with the deleted storage? I tried to block NSPsistentStoreCoordinator and unlock it after the operation was completed, but this did not help - all my attempts led to a deadlock. This always happens on this line (executed in the main thread):

[self.persistentStoreCoordinator removePersistentStore: store error: &error]; 
+6
source share
3 answers

I have not tried this, but from the docs on the moc setPersistentStoreCoordinator: ...

The coordinator provides a managed object model and handles survivability. Note that multiple contexts can be shared by the coordinator.

This method throws an exception if the coordinator is zero. If you want to "disconnect" a context from its permanent repository coordinator, you should simply set all strong context references to zero and allow it to be freed normally.

This suggests that the safe way to remove psc is to first have each thread with a moc release (Nil-out link to it in the ARC), then execute removePersistentStore:

+2
source

I would try using the approach described here (section Parent / Child Contexts): Multi-Context CoreData

Basically, your PSC has only one MOC associated with it (parent MOC). Other threads have their own MOCs, and their parentContext set to the main MOC (the one associated with the PSC).

Then you can try something like this:

 // Save each child MOC for (NSManagedObjectContext *moc in self.someChildMOCs) { [moc performBlockAndWait:^{ // push to parent NSError *error; NSAssert([moc save:&error]); moc.parentContext = nil; }]; } // Save parent MOC to disk [self.mainMOC performBlockAndWait:^{ NSError *error; NSAssert([mainMOC save:&error]); }]; [self.persistentStoreCoordinator removePersistentStore:store error:&error]; mainMOC.persistentStoreCoordinator = nil; 
+1
source

Is there a safe way to remove persistent storage (and create a new one) in an application where other threads use the NSManagedObjectContext associated with the deleted storage?

This should be safe if you can ensure that no live managed objects try to access persistent storage. This part is crucial: you have to make sure that there are no live objects of any type that have been downloaded or linked to the old persistent storage or otherwise connected to it.

You can do this by dropping each context of the managed entity:

 [managedObjectContext performBlockAndWait:^{ [managedObjectContext reset]; }]; 

Once you have done this for each context of the managed entity, you can delete the persistent storage.

Note that if you have any managed objects that have been extracted from these contexts, you must destroy them immediately without reading or writing the attribute values ​​or using them in any way. These objects may need to use context for various reasons, but after calling reset context knows nothing more about them. Get rid of them right away (ideally even before calling reset), because they are time bombs waiting to explode your application the moment you touch them.

+1
source

All Articles