Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I efficiently wipe my Core Data store when I'm simply storing the data in memory (not to disk)?

I'm using Core Data with an in-memory store, and I want to wipe it completely at some point. Most of the questions that I've found that relate to this are in regards to an on-disk store and involve deleting the store file or all the managed objects.

Is there a simpler way when it's in-memory? Can I just set something to nil and be done with it?

like image 732
Doug Smith Avatar asked Apr 25 '14 03:04

Doug Smith


People also ask

How do I clear my core data?

One approach to delete everything and reset Core Data is to destroy the persistent store. Deleting and re-creating the persistent store will delete all objects in Core Data.

Where does core data store Data?

The persistent store should be located in the AppData > Library > Application Support directory. In this example you should see a SQLite database with extension . sqlite. It is possible that you don't see the persistent store in the Application Support directory.

What is NSManagedObjectContext?

An object space to manipulate and track changes to managed objects.


1 Answers

In the case of an in-memory store remove the store from the NSPersistentStoreCoordinator using removePersistentStore:error:. At that point you can create a new in-memory store attached to the coordinator if you want, which will give you a blank slate at the store level - which seems to be the focus of your question.

Note that if you are retaining managed objects that you fetched from an NSManagedObjectContext those may still stick around, and when a fault is fired on them after you have removed your in-memory store they can throw exceptions. It's advisable that if this is likely (usually because you are using a single context, or are not good about using Instruments to track memory use) that you also call reset on your managed object context(s) and remove any lingering strong references to managed objects.

So using your code: When you create the in-memory store, specify a URL so you can identify it later:

if (![_persistentStoreCoordinator addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:[NSURL URLWithString:@"memory://0"] options:nil error:&error]) {

In your resetStack method you would remove it after you reset and removed your managed object context(s):

[[self persistentStoreCoordinator] removePersistentStore:[[self persistentStoreCoordinator] persistentStoreForURL:[NSURL URLWithString:@"memory://0"] ] error:&error];

If you do not reset and remove the context(s) first, you will start to see exceptions as the objects get faults fired that no longer have a store to go to.

You should listen for the notifications NSPersistentStoreCoordinatorStoresDidChangeNotification and NSPersistentStoreCoordinatorStoresWillChangeNotification anywhere you are using Core Data, so that when a store is added or removed you can act accordingly. For example, if you call your resetStack method that removes a store, you should see the NSPersistentStoreCoordinatorStoresWillChangeNotification and use that opportunity to stop whatever you are doing that may be accessing that store. When NSPersistentStoreCoordinatorStoresDidChangeNotification is received, you would complete your tear down of objects or processes that may be using Core Data - like an NSFetchedResultsController that may be attempting to access the store that was just removed. Once the old store has been removed you want to add a new, clean one. When that happens you will get the same notifications, with payloads that indicate a store was added - and at that time you can create new managed object contexts and fetched results controllers to replace the old ones.

This is all actually a lot simpler than it sounds. Nonetheless, make sure you're doing all of this for the right reasons.

like image 192
quellish Avatar answered Sep 28 '22 03:09

quellish