2013-04-16 2 views
3

Я посмотрел на каждый похожий вопрос, который я могу найти, и ни одно из их решений не работает для меня.Ошибка CoreData в контексте сохранения, NSPersistentStoreCoordinator не имеет постоянных магазинов

Одна из проблем может заключаться в том, что добавление сущностей в контекст (который преуспевает) и сохранение контекста происходят в другом потоке после того, как я верну JSON и проанализирую его из webAPI. Но контекст настраивается при первом использовании управляющего контекста и постоянного хранилища, как вы можете видеть ниже. Таким образом, это будет в этой теме после разбора, где это происходит.

Точная ошибка:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This NSPersistentStoreCoordinator has no persistent stores. It cannot perform a save operation.' 

Я попытался удалить приложение из тренажера, так как это было предложено, не изменился.

Вот мой класс CoreDataHelper, что я использую, и есть только один экземпляр его в моем приложении, ошибка происходит, когда я звоню метод saveContext на помощнике после добавления новых элементов в контекст:

@implementation CoreDataHelper 

@synthesize managedObjectContext = _managedObjectContext; 
@synthesize managedObjectModel = _managedObjectModel; 
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator; 

#pragma mark - Application's Documents directory 

// Returns the URL to the application's Documents directory. 
- (NSURL *)applicationDocumentsDirectory 
{ 
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory 
                inDomains:NSUserDomainMask] lastObject]; 
} 

- (void)saveContext 
{ 
    NSError *error = nil; 
    if (self.managedObjectContext != nil) { 
     if ([self.managedObjectContext hasChanges] && ![self.managedObjectContext save:&error]) { 
      // Replace this implementation with code to handle the error appropriately. 
      // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
      abort(); 
     } 
    } 
} 

- (void)dealloc { 

    [self saveContext]; 
} 

#pragma mark - Core Data stack 

// Returns the managed object context for the application. 
// If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application. 
- (NSManagedObjectContext *)managedObjectContext 
{ 
    if (_managedObjectContext != nil) { 
     return _managedObjectContext; 
    } 

    NSPersistentStoreCoordinator *coordinator = self.persistentStoreCoordinator; 
    if (coordinator != nil) { 
     _managedObjectContext = [[NSManagedObjectContext alloc] init]; 
     [_managedObjectContext setPersistentStoreCoordinator:coordinator]; 
    } 
    return _managedObjectContext; 
} 

// Returns the managed object model for the application. 
// If the model doesn't already exist, it is created from the application's model. 
- (NSManagedObjectModel *)managedObjectModel 
{ 
    if (_managedObjectModel != nil) { 
     return _managedObjectModel; 
    } 
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"]; 
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 
    return _managedObjectModel; 
} 

// Returns the persistent store coordinator for the application. 
// If the coordinator doesn't already exist, it is created and the application's store added to it. 
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator 
{ 
    if (_persistentStoreCoordinator != nil) { 
     return _persistentStoreCoordinator; 
    } 

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"UserGroupTV.sqlite"]; 

    NSError *error = nil; 
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] 
            initWithManagedObjectModel:[self managedObjectModel]]; 

    // needed for lightweight migrations 
    NSMutableDictionary *options = [NSMutableDictionary dictionary]; 
    [options setObject:[NSNumber numberWithBool:YES] 
       forKey:NSMigratePersistentStoresAutomaticallyOption]; 
    [options setObject:[NSNumber numberWithBool:YES] 
       forKey:NSInferMappingModelAutomaticallyOption]; 

    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType 
                configuration:nil 
                  URL:storeURL 
                 options:options 
                  error:&error]) { 

     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" 
                  message:[error localizedDescription] 
                  delegate:self 
                cancelButtonTitle:@"OK" 
                otherButtonTitles:nil, nil]; 
     [alertView show]; 
    } 

    return _persistentStoreCoordinator; 
} 


@end 

ETA: Я видел, как это упоминалось, но как/где я могу удалить локальную папку на компьютере, где хранится файл sql?

ответ

3

У меня нет четкого среза ответ, но вот несколько вещей, чтобы посмотреть на:

  1. Положите несколько входа в систему, где вы создаете persistentStoreCoordinator. Если возникает ошибка при добавлении хранилища во время создания, вы можете его поймать.

  2. Вы упомянули, что вы сохраняете контекст управляемого объекта в фоновом потоке. NSManagedObjectContext не является потокобезопасным, и вы должны использовать только определенный контекст в потоке, на котором он был создан. У вас должен быть, как минимум, один контекст на поток. Вы можете наблюдать «NSManagedObjectContextDidSaveNotification» и объединять изменения в свой основной контекст.

+0

Там есть код, если есть ошибка (возвращаемое значение равно нулю для магазина), когда я создаю persistentStoreCoord, он выведет вид предупреждения. Это не происходит. –

+0

Проверка нулевого возврата не улавливает этот случай. Это действительно так, чтобы создать «NSPersistentStoreCoordinator» без магазинов. Вам нужно проверить, был ли добавлен ваш конкретный магазин. Скорее всего, нет. Кроме того, единственный раз, когда я столкнулся с этой ошибкой, было то, что мое приложение запускалось в фоновом режиме. Не может быть вашей проблемой, но см. Http://stackoverflow.com/questions/12845790/how-to-debug-handle-intermittent-authorization-denied-and-disk-i-o-errors-wh. – XJones

0

Оказывается, я удалял магазин и не воссоздавал его каждый раз, когда я вспоминал веб-API. Моя первоначальная цель состояла в том, чтобы очистить базу данных каждый раз, когда пользователь хотел обновить список видео, вызвав api, и я удалял все объекты, а затем удалял магазин и забывал его воссоздать. Вот моя базовая схема обновления данных, я просто удалил все ниже вызова saveContext.

- (void)resetDataBase { 

    [self deleteAllObjects:@"Speaker"]; 
    [self deleteAllObjects:@"Tag"]; 
    [self deleteAllObjects:@"UserGroup"]; 
    [self deleteAllObjects:@"Video"]; 

    [_coreDataHelper saveContext]; 

    // REMOVED BELOW and it worked 
    NSPersistentStore * store = [[_coreDataHelper.persistentStoreCoordinator persistentStores] lastObject]; 
    if (store) { 
     NSError * error; 
     [_coreDataHelper.persistentStoreCoordinator removePersistentStore:store error:&error]; 
     if (error) { 
      [self showError:error]; 
     } 
    } 

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"UserGroupTV.sqlite"]; 
    [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]; 
} 
+1

Было бы полезно упомянуть об этом в вопросе. :) –

+0

lol. Я забыл спросить, если вы явно удаляете магазин за пределами кода, которым вы поделились! – XJones

+0

@Mark W Я также сталкиваюсь с аналогичной проблемой. Может ли это произойти из-за сохранения manageContext в фоновом потоке? Действительно застрял в этом ... – rhlnair

Смежные вопросы

 Смежные вопросы