Основные данные: как мне сохранить без сохранения? - PullRequest
0 голосов
/ 28 января 2010

Я пытаюсь отладить очень гнусную проблему с некоторым кодом iPhone Core Data.

Настройка такова: у меня есть поток, который существует для опроса веб-сервиса и отправки его результатов через NSNotification в основной поток (переданный в userDict, связке строк и NSNumber с). Я использую библиотеку уведомлений Тима Хэтчера , чтобы перейти к основному потоку.

NSDictionary* userDict = [Message userDictFromXML:el];
if (userDict != nil)
{
   [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"InsertMessage" object:nil userInfo:userDict];
}

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

Однако у меня возникают проблемы с этим, но не сразу. После того, как поток опубликовал свои результаты в главном потоке и сохранил новый объект в контексте, я могу выполнить определенную серию операций (включая NSFetchRequest и пару назначений отношений), что приводит к EXC_BAD_ACCESS при попытке получить доступ к одному из свойств извлеченного управляемого объекта.

Другая забавная вещь в том, что я могу решить проблему. Я могу сделать это, поместив один [userDict retain] в поток перед тем, как поместить его внутрь NSNotification, который будет отправлен в основной поток для сохранения в управляемом объекте. Не имеет значения, если я защищаю объекты друг от друга, создавая новый NSString, как только я получу значения в принимающем потоке, он все равно потерпит крах без этого retain.

NSDictionary* userDict = [Message userDictFromXML:el];
if (userDict != nil)
{
   [userDict retain]; // NOW THIS WORKS (???)
   [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"InsertMessage" object:nil userInfo:userDict];
}

Что дает ???

Ответы [ 2 ]

2 голосов
/ 28 января 2010

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

Если у вас есть Snow Leopard, попробуйте запустить с включенным NSZombieEnabled и используйте инструмент Инструменты ObjectAlloc. Когда зомби будет освобожден, вы можете щелкнуть и найти список всех мест, в которых объект был сохранен и освобожден.

0 голосов
/ 28 января 2010

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

...