views:

72

answers:

1

I'm trying to do a CoreData DB reset by removing a store and copying a default version in its place. The following works fine in the simulator, but when it runs on a device (testing using iOS 3.1.3 and 3.2.1) the app acts as if the database was never reset until the app is restarted. After a restart the newly initialized database is used, and everything is fine. Is there some kind of background cacheing going on that needs notification of the new store?

[I am doing error checking below, just deleting those lines for the sake of clarity. Of course, no errors are occuring]

-(void)initializeUserData {
NSError *error = nil;
NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"db.sqlite"];
NSURL *storeURL = [NSURL fileURLWithPath:storePath];

[self.managedObjectContext lock];
[self.managedObjectContext reset];

NSPersistentStore *store = [persistentStoreCoordinator persistentStoreForURL:storeURL];
[persistentStoreCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storePath error:&error];

// copy the pre-populated database file
NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"db" ofType:@"sqlite"];
[[NSFileManager defaultManager] copyItemAtPath:defaultStorePath toPath:storePath error:&error];

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                         [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                         [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
                         nil];
[persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error];

[self.managedObjectContext unlock];
} 

Edit: Not sure if this means anything, but as a sanity check I turned on -com.apple.CoreData.SQLDebug and get the following logged after the call to addPersistentStoreWithType:

CoreData: annotation: Connecting to sqlite database file at "..."

The following (which I would expect to come at the call to removePersistentStore:) is logged after the app returns to the main loop:

CoreData: annotation: Disconnecting from sqlite database.

There isn't a followup "Connecting to database" message later, despite the fact that the database is being accessed, so I assume that the odd order of those log entries is just a side-effect of how logging is done...

+1  A: 

You need to capture the BOOL returns of:

[persistentStoreCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storePath error:&error];

... as I am pretty sure that neither will report an error if the file cannot be removed because it is in use. I imagine one or both is failing without error.

From your description is sounds like the context continues to use the persistent store and that it is never deleted until restart. I think the context cannot surrender the store because it has live objects connected to the store. That in turn prevents the persistentStoreCoordinator from surrendering the file which prevents the file manager from deleting it.

You appear to be using threading so another context using the same store could also be blocking its deletion.

Unless your using a document based pattern, I would advocate simply rebuilding the Core Data stack from scratch to avoid these complications.

TechZen
Ah, good call. Unfortunately that doesn't seem to be the issue. I added BOOL catches for both lines (and copyItemAtPath: for good measure), but none of them are failing. I'm not really using threading, the lock/unlock lines are just "just in case" lines that I added while debugging to see if it would fix something weird that I didn't know about. Sorry, I should have removed them before posting.I'm sorry, I'm new to this. Rebuilding the stack from scratch would mean releasing the ManagedObjectContext and PersistentStoreCoordinator, and re-creating the objects?
Tony
OK, yeah, figured it out. You're right, it's best just to nuke everything and start over from scratch. =)
Tony