Как сохранить PersistentStore

У меня следующая проблема:

У меня есть приложение с UITableView в качестве корневого представления. В этом tableView находятся разные записи, и для каждой записи (которую может создать пользователь) я также добавляю постоянное хранилище в мое приложение.

Поэтому, когда я запускаю приложение с нуля (без сохраненных данных и т. Д.) И добавляю запись, также создается persistentStore, и когда я нажимаю на tableViewCell, я могу сохранить данные в этом сгенерированном persistentStore. Это прекрасно работает, если я создаю запись, а также смотрю запись во время одного запуска.

НО

Если я закрываю приложение и запускаю снова, нажимаю на ту же запись, я получаю следующее сообщение об ошибке:

NSFetchRequest *allUsers = [[NSFetchRequest alloc] init];
[allUsers setAffectedStores:[NSArray arrayWithObject:[[self.tableViewContext persistentStoreCoordinator] persistentStoreForURL:storeURL]]];

* Завершение работы приложения из-за необработанного исключения "NSInvalidArgumentException", причина: '* - [NSArray initWithObjects: count:]: попытка вставить нулевой объект в объекты [0]'

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

Поэтому я думаю, что persistentStore не существует во втором запуске, поэтому он не сохраняется должным образом в первом запуске, где он был создан.

Итак, как я могу сохранить persistentStore после его добавления в persistentStoreCoordinator?

Обновить:

Я думаю, что я определил главную проблему. PersistentStoreCoordinator изменился после первого запуска. Итак, как мне сохранить все эти вещи (managedObjectContext, persistentStoreCoordinator) перед закрытием приложения?

Кто-нибудь может мне помочь?

Обновление 2

Вот как я создаю магазин:

    NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath = [searchPaths objectAtIndex:0];
    NSString* storeFileName = [NSString stringWithFormat:@"%@",newItem.name];
    NSURL *storeURL = [NSURL fileURLWithPath:[documentPath stringByAppendingPathComponent:storeFileName]];                            
     NSError* saveToStoreError;
    if(![[self.addContext persistentStoreCoordinator] addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&saveToStoreError]){
     NSLog(@"Error: %@, %@", saveToStoreError, [saveToStoreError userInfo]);
     abort();
    }
    else
    {
      NSError *saveStoreError;
      if(![self.addContext save:&saveStoreError])
      {
           NSLog(@"Saving Data wasn't possible!");
      }
    }

Обновление 3 Итак, после многих испытаний вот мои результаты:

  • Создание магазинов работает отлично. Я могу создать несколько магазинов, и я могу получить к ним доступ и заполнить их, пока я работаю в одном приложении.

Так что что-то меняется с перезапуском моего приложения. Я думаю, что ошибка должна быть связана с managedObjectContext, persistentStoreCoordinator или СОХРАНЕНИЕМ магазинов.

Должен ли я изменить какие-либо параметры в моем делегате приложения для настройки managedObjectContext или persistentStoreCoordinator?

Спасибо!

5 ответов

Решение

Это было просто легко.

Я не ставил addPersistentStoreWithType после перезапуска в представлении, где я пытался получить данные из этого магазина.

Извините за этот пост. Просто легко;-) bangingmyheadonthewall

То, как вы озвучиваете свою проблему, заставляет меня подозревать какую-то путаницу.

что persistentStore меняется после каждого перезапуска. Это обычный случай?

Да, это! NSPersistentStore является объектом target-C, как и любой другой объект. Как таковой он не является постоянным во всех запусках. Вы должны воссоздать его каждый раз.

Что является постоянным в NSPersistentStore, так это файл, на который он указывает. Но каждый раз, когда вы запускаете свое приложение, вы должны воссоздавать новый объект NSPersistentStore, возможно, делая его указателем на тот же файл (определяемый url аргумент initWithPersistentStoreCoordinator:configurationName:URL:options:).

Так как вы устанавливаете свой storeURL переменная?

Взгляните на приложение на основе окна в шаблонах XCode.

Это создаст для вас целый стек Core-Data - постоянное хранилище, координатор постоянного хранилища и контекст управляемого объекта.

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

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

Чтобы сохранить контекст управляемого объекта, используйте метод "save:" NSManagedObjectContext после добавления нового постоянного хранилища и перед закрытием приложения. Затем, чтобы проверить, правильно ли были добавлены постоянные хранилища, используйте метод persistentStores NSPersistentStoreCoordinator, чтобы определить действительные доступные хранилища.

Интересно, проблема не в том, что вызовы Core Data так сильно, как если бы / когда они вызывались?

Когда вы "закрываете приложение и запускаете снова" ... приложение перестает работать или оно становится фоновым? IIRC, который незначительно повлияет на то, что вызывается в вашем делегате приложения. В зависимости от того, как там все устроено, WRT Core Data, возможно, что-то случайно вызывается (или пропускается).

Мне было бы интересно посмотреть, что произойдет, если вы проследите через каждый отдельный метод, связанный с Базовыми данными, в вашем делегате приложения (или где бы они ни находились), чтобы увидеть, сможете ли вы поймать его с поличным. (Если где-то опубликован минимальный тестовый пример, пожалуйста, поделитесь!)

Другие вопросы по тегам