Несоответствие основных данных-fetch иногда ничего не возвращает
Я уже потратил несколько часов на это, и я не могу найти решение. Во-первых, некоторые спецификации того, что у меня есть:
- цель-c iOS 6 приложение с основными данными
- основные данные инициализируются из UIManagedDocument, который имеет автоматическое сохранение включено
- ManagedContext из UIManagedDocument хранится в статической переменной и повторно используется во всем приложении
- приложение использует RestKit, и я использую категорию ActiveRecord, что он обеспечивает.
у меня есть модель с Team entity. В приложении есть контроллер представления списка команд, который загружает команды из бэкэнда. Бэкэнд возвращает массив JSON, содержащий, среди прочего, идентификатор команды. Я храню этот идентификатор в поле " id " в моей модели, и, повторяя ответ сервера, я ищу, существует ли команда для данного идентификатора. Если это так, я только обновляю его информацию и передаю объект, если нет - я создаю его первым.
и вот где это становится странным. Это работает 90% времени. Я могу загрузить контроллер списка команды, пойти дальше в приложении, вернуться к контроллеру (который снова загружает данные), и все в порядке большую часть времени. Однако время от времени мой запрос fetch ничего не возвращает. Как в:
NSArray *results = [context executeFetchRequest:request error:&error];
вернет пустой массив, и ошибка также пуста. На сервере ничего не меняется. Запрос, когда я пытаюсь отладить его, выглядит следующим образом:
<NSFetchRequest: 0x127a0e20> (entity: Team; predicate: (id == "123"); sortDescriptors: ((null)); limit: 1; type: NSManagedObjectResultType; )
когда я просматриваю sqlite магазин во внешнем приложении, я вижу, что элемент команды для этого идентификатора присутствует, и в других 90% раз он действительно загружается. Что еще более странно, когда я включил SQLDebug, я вижу:
2013-04-12 12:00:27.934 SportLink[10831:c07] CoreData: annotation: fetch using
NSSQLiteStatement <0x12656d10> on entity 'Team' with sql text 'SELECT 0, t0.Z_PK,
t0.Z_OPT, t0.ZACI1, t0.ZACI2, t0.ZACI3, t0.ZALTFIRSTNAME, t0.ZALTSECONDNAME, t0.ZCOLOR1,
t0.ZCOLOR2, t0.ZGENDER, t0.ZICON, t0.ZID, t0.ZLOCATION, t0.ZLOGO1, t0.ZLOGO2, t0.ZNAME,
t0.ZTYPE, t0.ZSPORT FROM ZTEAM t0 WHERE t0.ZID = ? LIMIT 133' returned 6 rows
это означает, что резервное хранилище фактически извлекло данные, но по какой-то причине не передало их. Теперь:
- Я делаю все в главном потоке, так что это не проблема
- Я считаю, что автосохранение тоже не является проблемой, потому что это может бывает даже, когда я закрываю приложение и открыть его снова с уже имеющихся данных.
есть идеи о том, что здесь происходит?
Edit: я профилировал приложение с инструментами. Я просто вошел в проблемный VC, затем вошел в его дочерний контроллер и ушел, повторил это пару раз, пока проблема не начала проявляться. Вот результаты. Может быть, отсюда будет легче узнать, что происходит:
1 ответов
после нескольких дней расследования, я, наконец, нашел причину этой ошибки. Код, который получал Team entity, выглядел так:
Team *team = [Team findFirstByAttribute:WSK_ID withValue:data[WSK_ID] inContext:moc];
WSK_ID
- это просто определение для @"id"
. data
это словарь, который я получил от RestKit, из ответа JSON. Поскольку он не был приведен к какому-либо типу, Это, вероятно, была NSString, в то время как id
свойство Team entity ожидало NSNumber. Хотя я не знаю, что это только не удалось иногда, изменяя этот бит кому:
Team *team = [Team findFirstByAttribute:WSK_ID withValue:@([data[WSK_ID] intValue]) inContext:moc];
т. е. приведение строки идентификатора в int, а затем бокс его с NSNumber Исправлена проблема.