Несоответствие основных данных-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, затем вошел в его дочерний контроллер и ушел, повторил это пару раз, пока проблема не начала проявляться. Вот результаты. Может быть, отсюда будет легче узнать, что происходит:

Instruments output

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 Исправлена проблема.