开发者

Recreate persistence store after removing previous sqlite store file

I would like to remove my sql lite file and set up the persistance store again.

//Explicitly write Core Data accessors

- (NSManagedObjectContext *) managedObjectContext {
if (managedObjectContext != nil) {

    return managedObjectContext;

}

NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];

if (coord开发者_如何学Pythoninator != nil) {

    managedObjectContext = [[NSManagedObjectContext alloc] init];

    [managedObjectContext setPersistentStoreCoordinator: coordinator];
}

    return managedObjectContext;
}

- (void) setManagedObjectContext:(NSManagedObjectContext *)managedObjectContext{}


- (NSManagedObjectModel *)managedObjectModel {
    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil] ;

    return managedObjectModel;
}

-(void) setManagedObjectModel:(NSManagedObjectModel *)managedObjectModel{}


- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }
    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory]    stringByAppendingPathComponent: @"Port.sqlite"]];    
    NSError *error = nil;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if(![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {

        NSLog(@"Could not create store ....  %@", error );
        /*Error for store creation should be handled in here*/
    }

return persistentStoreCoordinator;
}

I am trying to reset my scene like this

- (void)reset {
    // Release CoreData chain
    self.managedObjectContext = nil;
    self.managedObjectModel = nil;
    self.persistentStoreCoordinator = nil;

    // Delete the sqlite file
    NSError *error = nil;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory]    stringByAppendingPathComponent: @"Port.sqlite"]];  

    if ([fileManager fileExistsAtPath:storeUrl.path]){
        [fileManager removeItemAtURL:storeUrl error:&error];
    }
    self.managedObjectContext = [self managedObjectContext];
    self.managedObjectModel = [self managedObjectModel];
    self.persistentStoreCoordinator = [self persistentStoreCoordinator];

    // handle error...
}

I am getting an error while saving:

+ (BOOL)saveAll {
    // [self createStorage];
    NSError *error = nil;
    NSManagedObjectContext *managedObjectContext = [(WSSMobileAppsAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
    if (![managedObjectContext save:&error]) {
        NSLog(@"Error while saving %@", error);
        return FALSE;
    }
    return TRUE;
}

The error:

Error while saving Error Domain=NSCocoaErrorDomain Code=134030 "The operation couldn’t be completed. (Cocoa error 134030.)" UserInfo=0x7195ac0 {NSAffectedStoresErrorKey=(
    "<NSSQLCore: 0x714eee0> (URL: file://localhost/Users/.../Library/Application%20Support/iPhone%20Simulator/5.0/Applications/CEDB9019-1D64-4968-9BE7-57E1493B96EC/Documents/Port.sqlite)"
), NSUnderlyingError=0x7195a50 "The operation couldn’t be completed. (Cocoa error 4.)", NSFilePath=/Users/.../Library/Application Support/iPhone Simulator/5.0/Applications/CEDB9019-1D64-4968-9BE7-57E1493B96EC/Documents/Port.sqlite}

I only get the error if I run my reset function. I thought that setting:

self.managedObjectContext = nil;
self.managedObjectModel = nil;
self.persistentStoreCoordinator = nil;

...would solve the problem. Then everything would be recreated. Please help.


Thank you very much for your answers. Now there is no error but nothing gets stored if I run my reset. I do a fetch right after saving

if (![managedObjectContext save:&error]) {
    NSLog(@"Error while saving %@", error);
    return FALSE;
}
CoreDataPortService *c = [[CoreDataPortService alloc] init];
NSLog(@"Saved all.... got number of ports ... %d", [[c getPorts] count]);

I if don't run my reset method everything works as expected. What can be wrong?


You wrote a setter for your managedObjectContext, but it does nothing:

- (void) setManagedObjectContext:(NSManagedObjectContext *)managedObjectContext{}

When you do self.managedObjectContext = nil, all it does is call [self setManagedObjectContext:nil]. That does nothing. The instance variable managedObjectContext keeps the same value, and when you request it again with the getter, you still have the managedObjectContext that was associated with the deleted file. You need:

- (void) setManagedObjectContext:(NSManagedObjectContext *)_managedObjectContext {
    [managedObjectContext release];
    managedObjectContext = _managedObjectContext;
    [managedObjectContext retain];
}

And that's also assuming your managedObjectContext property is declared with the nonatomic modifier. If it's declared atomic, you will also need code to lock. Write the setters for managedObjectModel and persistentStoreCoordinator in a similar way.

@synthesize usually generates setters like that for you, but since you want to write your own getters, you have to write your own setters too. There might be a way to have @synthesize make only the setter for your property instead, but I can't remember.

Answer to follow up question. Maybe you are doing something like this:

NSManagedObjectContext *moc = self.managedObjectContext;
[self reset];
[self repopulateData:xmlFile];
NSError *error = nil;
if (![moc save:&error])
    [self logError:error];

If that's the case then you would be calling save on the old managed object context. Not sure what the outcome of that would be. Instead change the next-to-last line to

if (![self.managedObjectContext save:&error])

to make sure you are using the current managed object context.

Or similarly you might be trying to read from the old managed object context. Check the address of any managed object context pointers you are using and make sure they are pointing to the same thing as the new managed object context you created in reset.

If that's not the problem, I have no idea. You will have to try to gather more information as to why it's not working. For example, does the file exist at all? Does its size increase when you add the data? Is the data written to the file, but can't be read?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜