Какая эффективная стратегия контекста / координатора CoreData для этого общего шаблона приложения?

У меня есть общий шаблон приложения: пользователь вводит данные в контроллер основного представления, а затем просматривает их в таблице в контроллере модального представления, где строки могут быть удалены или изменены. Я следовал общей стратегии дизайна из Стэнфордского курса iPhone, но где-то все пошло не так, и все, что я получил, - это SIGABRT и исключения вроде «Незаконная попытка установить связь 'xyz' между объектами в разных контекстах».

Как и в Стэнфордском курсе, я использую одноэлементный класс под названием «База данных», который должен возвращать тот же контекст при каждом запросе. Итак, первые команды в моем методе viewDidLoad на главном контроллере представления:

 dbsingleton = [Database sharedInstance];
 nmocontext = [dbsingleton managedObjectContext];

nmocontext - это ivar, который я использую во всем контроллере представления. Когда пользователь хочет увидеть другой контроллер представления с таблицей, я выделяю-инициализирую его, а затем представляю модально. (У него есть NSFetchedResultsController, который предоставляет данные из моего магазина.) Я пробовал здесь различные стратегии:

  • Я сделал NSFetchedResultsController сохраняемым свойством, установленным главным контроллером представления.
  • Я сделал NSManagedObjectContext сохраняемым свойством, установленным главным контроллером представления; и
  • Я использовал синглтон внутри, повторяя эти две строки кода выше в начале метода viewDidLoad контроллера табличного представления.

Что бы я ни выбрал, одна проблема, которую я просто не могу решить, заключается в том, что после того, как пользователь закрывает и освобождает контроллер представления таблицы (и его NSFetchedResultsController), я начинаю получать сбои в контроллере основного представления при доступе к хранилищу (например, " Незаконная попытка "ошибка, упомянутая выше).

Каковы наилучшие методы работы с этим распространенным шаблоном приложения? Я все еще надеюсь сделать это приложение совместимым с iPhone SDK 3.x, но, похоже, у меня меньше сбоев, когда я использую iOS 4 - если есть основные проблемы с 3.x, которые вызывают у меня проблемы, пожалуйста, позвольте мне знаю, и я могу настроить таргетинг только на iOS 4.

Спасибо!




Ответы (2)


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

Вы заявили недвижимость

@property (retain, nonatomic) NSManagedObjectContext* nmocontext;

правильно ли вы освобождаете ivar nmocontext в dealloc? Если да, ваша проблема - задание

nmocontext = [dbsingleton managedObjectContext];

Это никогда не сохраняет nmocontext в вашем контроллере просмотра, но вы освобождаете его при освобождении.

Второй:

«Незаконная попытка установить связь« xyz »между объектами в разных контекстах».

Это не проблема управления памятью, но вы, вероятно, создали еще один новый контекст для добавления объектов (например, в образцах iphone с данными ядра Apple) и попытались установить NSManagedObject как связь из другого контекста.

person Martin Brugger    schedule 12.09.2010
comment
Это полезно ... Удаление сообщения о выпуске помогает в симуляторе iOS 4.0, но у меня все еще возникают сбои на моем тестовом устройстве 3.x. Я проверил ваш профиль, и вы выглядите блестяще с CoreData - какой была бы ваша общая стратегия для этого типа приложений? Мне интересно, не слишком ли я усложняю одноэлементный класс? Какой лучший подход для создания контекстов и FetchedResultsControllers, когда вам нужно получить доступ к одному и тому же хранилищу CoreData с разных контроллеров представления? - person ed94133; 13.09.2010
comment
Маркус С. Зарра рекомендует внедрение зависимостей для совместного использования контекста. Этот вопрос уже обсуждался здесь: stackoverflow.com/questions/3174610/ - person Martin Brugger; 13.09.2010
comment
Спасибо. Я избавился от синглтона и передаю контекст как свойство повсюду. Это было полезно для предотвращения сбоев во время выполнения. Однако, когда я пишу в кеш, я как-то мешаю ему - при последующих чтениях я получаю фатальную ошибку вокруг своего постоянного кеша. Думаю, мне стоит этот пост как отдельный вопрос. Спасибо. - person ed94133; 15.09.2010

Похоже, у вас неправильно настроен синглтон.

Синглтон должен перекрывать release, чтобы ничего не делать, чтобы при отправке сообщения о выпуске ничего не происходило. Если вы не переопределите release, то любой случайный фрагмент кода в любом месте приложения может убить синглтон и полностью уничтожить цель использования синглтона. В следующий раз, когда вы вызовете singleton, вы фактически получите еще один новый объект, который в этом случае также возвращает новый контекст управляемого объекта.

См. Руководство по основам какао: создание экземпляра синглтона.

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

person TechZen    schedule 14.09.2010