Повторное создание хранилища после удаления предыдущего файла хранилища sqlite - PullRequest
1 голос
/ 16 сентября 2011

Я хотел бы удалить файл sql lite и заново настроить хранилище постоянных файлов.

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

Если мой метод сброса не запущен, все работает как положено. Что может быть не так?

1 Ответ

0 голосов
/ 16 сентября 2011

Вы написали установщик для вашего управляемогоObjectContext, но он ничего не делает:

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

Когда вы делаете self.managedObjectContext = nil, все, что он делает, это вызывает [self setManagedObjectContext:nil].Это ничего не делает.Переменная экземпляра managedObjectContext сохраняет то же значение, и когда вы запрашиваете его снова с помощью получателя, у вас все еще есть файл managedObjectContext, связанный с удаленным файлом.Вам необходимо:

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

И это также при условии, что ваше свойство managedObjectContext объявлено с неатомарным модификатором.Если он объявлен как атомарный, вам также понадобится код для блокировки.Напишите сеттеры для managedObjectModel и persistentStoreCoordinator аналогичным образом.

@ synthesize обычно генерирует такие сеттеры для вас, но, так как вы хотите писать свои собственные геттеры, вы должны написать свои собственные сеттеры.Может быть, есть способ заставить @synthesize сделать только установщик для вашего свойства, но я не могу вспомнить.

Ответ на следующий вопрос.Может быть, вы делаете что-то вроде этого:

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

, чтобы убедиться, что вы используете текущий контекст управляемого объекта.

Или аналогичным образом вы можете пытаться читать со старого управляемого объектаконтекст.Проверьте адреса любых указателей контекста управляемого объекта, которые вы используете, и убедитесь, что они указывают на то же самое, что и новый контекст управляемого объекта, который вы создали при сбросе.

Если это не проблема, я понятия не имею.Вам нужно будет попытаться собрать больше информации о том, почему это не работает.Например, существует ли файл вообще?Увеличивается ли его размер при добавлении данных?Данные записаны в файл, но не могут быть прочитаны?

...