Core data 删除以前的sqlite存储文件后重新创建持久性存储

Core data 删除以前的sqlite存储文件后重新创建持久性存储,core-data,ios-4.2,Core Data,Ios 4.2,我想删除我的SQLLite文件并再次设置持久性存储 //Explicitly write Core Data accessors - (NSManagedObjectContext *) managedObjectContext { if (managedObjectContext != nil) { return managedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persisten

我想删除我的SQLLite文件并再次设置持久性存储

//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}
…将解决问题。然后一切都会被重新创造。请帮忙


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

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

如果不运行重置方法,则一切正常。有什么问题吗?

您为managedObjectContext编写了一个setter,但它什么也不做:

- (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的设置程序

@Synthesis通常会为您生成这样的setter,但既然您想编写自己的getter,那么您也必须编写自己的setter。也许有一种方法可以让@synthesis只为您的属性生成setter,但我不记得了

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

NSManagedObjectContext *moc = self.managedObjectContext;
[self reset];
[self repopulateData:xmlFile];
NSError *error = nil;
if (![moc save:&error])
    [self logError:error];
如果是这种情况,那么您将在旧的托管对象上下文上调用save。我不确定这会有什么结果。而是将倒数第二行改为

if (![self.managedObjectContext save:&error])
以确保您正在使用当前的托管对象上下文

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


如果这不是问题,我也不知道。你必须试着收集更多的信息来解释为什么它不起作用。例如,文件是否存在?添加数据时,其大小是否会增加?数据是否已写入文件,但无法读取?

小问题。如果您想要自定义getter,那么您还必须编写自定义setter,这是不正确的。(反之亦然。)如果所需的方法不存在,@sythesize创建它,如果它存在,则使用该方法。你可以随心所欲地混搭。好吧,那是个更好的答案。删除
-(void)setManagedObjectContext:(NSManagedObjectContext*)managedObjectContext{}
并添加
@synthetic managedObjectContext
。非常感谢您的回答。@user87444--如果此答案解决了您的问题,请点击旁边的复选标记,使其显示为已回答。错误已消失,但必须执行其他操作才能保存。我认为问题的关键是您希望删除所有数据。不如果删除文件并删除内存中的managedObjectContext,则数据将消失。如果您试图删除文件并从内存内容中重新创建它,那么您将需要一种不同的方法。我真的无法想象你为什么要这么做。在正常情况下,持久存储将与托管对象上下文中的内容保持同步。我想删除数据。是否也可以删除该文件。这是因为有时我会更改实体。你说,“如果我运行重置,则不会存储任何内容”。听起来您不希望存储任何内容,即删除所有内容。您的意思是运行重置,然后添加对象,然后保存,之后就没有对象了吗?很抱歉让您感到困惑。当我运行重置时,我想删除所有内容。删除所有内容后,我想再次解析xml并存储对象的状态。因此,存储XML的状态是可行的,我以前不运行重置。所以1。重置所有对象(删除XML)2。解析新的XML并存储它。第二步现在是我的问题。如果我之前没有运行步骤1,那么步骤2可以工作。
if (![self.managedObjectContext save:&error])