2010-09-09 3 views
6

Я думаю, что я понимаю сообщение об ошибке: CoreData не смог выполнить ошибку, но я не уверен, как мне с этим справиться.CoreData не смог выполнить ошибку при обновлении объектов службой HTTP

У нас есть приложение, в котором мы используем Core Data для сохранения данных, возвращаемых службой JSON. Сегодня я делаю следующее.

  1. Fetch локального объекта из постоянного хранилища и вернуться к UI
  2. Задать сервер, если объект обновляется - когда я получаю ответ, я обновить ядро ​​данные управляемого объекта
  3. обновление пользовательского интерфейс с обновленным объектом

проблема; даже если я не использую несколько потоков, я иногда получаю сообщение об ошибке, когда HTTP-запрос удаляет управляемые объекты, которые мой пользовательский интерфейс сохранил. Я попытался извлечь объекты с returnObjectsAsFaults в NO. Я думал, что тогда я могу получить доступ ко всем отношениям и свойствам управляемого объекта, даже если он был удален (пока мой пользовательский интерфейс сохранил его).

Как решить эту проблему?

Я думал, что могу использовать отдельный NSManagedObjectContext для чтения и записи. Я сделал это испытание:

MyAuthorMO *authorUpdate = [[MyAuthorMO alloc] init]; // I have made this init insert the object into the updateContext 
authorUpdate.firstname = @"Hans"; 
authorUpdate.lastname = @"Wittenberg"; 
authorUpdate.email = @"[email protected]"; 

NSManagedObjectContext *updateContext = [[MyCoreManager getInstance] managedObjectContext]; 

NSError *error = nil; 
[updateContext save:&error]; 

NSManagedObjectContext *readContext = [[MyCoreManager getInstance] readOnlyContext]; 

NSFetchRequest *fetchRequest = [managedObjectModel fetchRequestFromTemplateWithName:@"authorByEmail" substitutionVariables:[NSDictionary dictionaryWithObject:@"[email protected]" forKey:@"EMAIL"]]; 
[fetchRequest setReturnsObjectsAsFaults:NO]; 

NSArray *authors = [readContext executeFetchRequest:fetchRequest error:&error]; 

MyAuthorMO * readAuthor = [authors objectAtIndex:0]; 

// Delete the author with update context: 
[updateContext deleteObject:authorUpdate]; 
[updateContext save:&error]; 

NSLog(@"Author: %@ %@, (%@)", readAuthor.firstname, readAuthor.lastname, readAuthor.email); 

Журнал выдается только штраф до тех пор, как я использую readContext для выборки. Если я использую updateContext для извлечения, я получаю исключение. Это выглядит многообещающе, но я боюсь, что у меня возникнут проблемы на более позднем этапе. Рано или поздно я, вероятно, попытаюсь получить доступ к объекту, который полностью не получен (ошибка). Как я могу достичь такого поведения, которое я ищу?

+0

Ник, вы, вероятно, правы. Я прочитал свои предыдущие сообщения и принял лучшие решения. Спасибо за ваш комментарий. – Andi

ответ

14

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

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

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

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

+1

Я согласен с вами, но имею некоторые последующие вопросы. Я не сохраняю МО, но, если я его где-то использую, его можно, вероятно, сохранить без меня, зная об этом. Можно ли добавить MO в NSArray или NSDictionary? Если это так, то оно будет сохранено ... Нужно ли мне объединить контекст, или я могу просто ждать следующего раза, когда я беру из «read» -context »? Я боюсь, что мои данные повреждены, если я объединить два контекста, в которых удаляется объект, который я в настоящее время рендеринга (с «write» -context). – Andi

+1

Я не понял.Я имел в виду, что вы не должны пытаться сохранить управляемый объект, который удалил контекст. Это будет беспорядочно. Вы должны объединить контекст, но вам нужно будет заморозить интерфейс во время обновления модели. Посмотрите, как NSFetchedResultsController обрабатывает эту точную проблему с обновлением данных, пока данные отображаются в таблице. Пользователь может полностью замораживать пользовательский интерфейс. Если у вас есть данные, которые могут быть удалены во время работы с ним, вам нужно переосмыслить свой дизайн. Пользователь должен контролировать такие удаления. – TechZen

0

У меня была такая же проблема в моей базе данных, потому что я обращаюсь к объекту, который didnt существует (потому что я удаляю его с другим связанным объектом). Мое решение состояло в том, чтобы установить «Нет действий» в моих отношениях.

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