2011-09-16 63 views
1

我想删除我的sql lite文件并重新设置持久性存储。删除先前的sqlite存储文件后重新创建持久性存储

//Explicitly write Core Data accessors 

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

    return managedObjectContext; 

} 

NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 

if (coordinator != 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; 
} 

我想重置我的场景是这样

- (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... 
} 

同时节省我得到一个错误:

+ (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; 
} 

错误:

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} 

我只如果我运行我的重置功能,会得到错误。我认为设置:

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

...将解决问题。然后一切都会重新创建。请帮忙。


非常感谢您的回答。现在没有错误,但是如果我运行重置,则不会有任何存储。我在保存后立即执行提取操作

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]); 

我如果不运行我的重置方法,一切都按预期工作。什么可能是错误的?

+0

我认为这一点是你想删除所有的数据。没有?如果删除该文件并删除内存中的managedObjectContext,则数据将消失。如果你想删除文件并从内存中重新创建文件,那么你需要一种不同的方法。我无法想象为什么你会这么做。在正常情况下,持久性存储将与您在托管对象上下文中保持同步。 – morningstar

+0

我想删除这些数据。是否也可以删除文件。那是因为有时候我改变实体。 – pethel

+0

你说,“如果我运行我的重置,没有任何东西被存储”。听起来你不想存储任何内容,即删除了所有内容。你的意思是你运行重置,然后添加对象,然后保存,并且之后没有对象? – morningstar

回答

0

你写了一个二传手您managedObjectContext,但不起任何作用:

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

当你这样做self.managedObjectContext = nil,它是所有调用[self setManagedObjectContext:nil]。那什么都不做。实例变量managedObjectContext保持相同的值,并且当您使用getter再次请求它时,您仍然拥有与删除的文件关联的managedObjectContext。您需要:

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

而且还假设您的managedObjectContext属性是使用非原子修饰符声明的。如果它被声明为原子的,你还需要代码来锁定。以类似的方式编写managedObjectModel和persistentStoreCoordinator的setter。

@synthesize通常会为您生成这样的setter,但由于您想编写自己的getter,因此您也必须编写自己的setter。可能有一种方法让@synthesize改为只为你的属性设置setter,但我不记得了。

回答后续问题。也许你正在做这样的事情:

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

如果是这种情况,那么你会调用保存在旧的托管对象的上下文。不确定那会是什么结果。改为将倒数第二行改为

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

确保您使用的是当前托管对象上下文。

或者您可能试图从旧的托管对象上下文中读取。检查您正在使用的任何托管对象上下文指针的地址,并确保它们指向与您在重置时创建的新托管对象上下文相同的内容。

如果这不是问题,我不知道。你将不得不尝试收集更多的信息,为什么它不工作。例如,文件是否存在?添加数据时其大小是否增加?数据是否写入文件,但无法读取?

+1

小问候。这是不正确的,如果你想要自定义getter,你也必须编写自定义setter(反之亦然)。如果所需的方法不存在,@sythesize会创建它,如果存在,它会使用该方法。你可以混合和匹配所有你想要的。 – TechZen

+0

好的,那是更好的答案。删除' - (void)setManagedObjectContext:(NSManagedObjectContext *)managedObjectContext {}'并添加'@synthesize managedObjectContext'。 – morningstar

+0

非常感谢你的回答。 – pethel