2013-02-23 1 views
5

После добавления новой версии модели Core Data в мое приложение я выполнил легкую миграцию, по-видимому, успешно. Мигрированный файл загружен в порядке, но при первой попытке доступа к атрибуту через определенную связь приложение вылетает с NSRangeException: '*** -[__NSArrayM objectAtIndex:]: index 4294967295 beyond bounds [0 .. 35]'. Эта взаимосвязь отлично работала до миграции. Я знаю из других сообщений, что 4294967295 действительно -1, но единственное, что я могу идентифицировать с 36 пунктами в моем приложении/данных, это то, что в модели данных имеется 36 общих объектов (для справки, отношения, которые получаются, имеют 58 элементов в его таблице).NSRangeException после миграции данных Core

Вопрос:

Мой вопрос: на основе ошибки я получаю и устранение неполадок, что я сделал ниже, есть тип изменения схемы, которые могли бы пройти легкую миграцию, но коррумпированный данные по пути, приводящие к отмеченному исключению? Я попытаюсь сломать переход на более мелкие куски на несколько версий, чтобы изолировать или избежать проблемы, но было бы неплохо сосредоточиться на конкретных изменениях схемы, которые могут быть ошибочными.

Неудача:

Неудача происходит с помощью следующего кода в «MyObject»:

[[self object2] text]; 

object2 отношения к одному, не по желанию оба пути и ни вперед, ни обратная связь была изменена между моделями данных. Атрибут text, вероятно, не имеет значения, поскольку при возникновении ошибки awakeFromFetch не достигается в объекте2. Если я присвою значение [self object2] переменной перед вышеуказанным оператором, назначение будет успешным и сообщит data: <fault>.

База данных:

Глядя на базу данных в sqlite3, я заметил следующее:

  1. значения индекса для прямых и обратных отношений являются правильными в каждой таблице.
  2. В таблице object2 есть две колонки для обратной связи, а не одна перед миграцией (ZMYOBJECT как и до и Z2_MYOBJECT, которая пуста для всех строк). Никаких других отношений не было добавлено, чтобы объяснить эту колонку.
  3. В таблице Z_PRIMARYKEY все записи после миграции показаны -1 для Z_MAX, тогда как до миграции они показали нуль для пустых таблиц и максимального номера строки для заполненных таблиц. Ручное обновление Z_MAX до правильных значений не помогло с исключением. Все значения Z_SUPER были верны.

Я установил картографическую модель, чтобы увидеть, что что-то похожее на ошибки с автоматическими сопоставлениями, но все выглядело отлично.

Общая схема изменения:

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

В целевой версии модели данных были добавлены двадцать два объекта, некоторые верхние и некоторые субистемы, с десятками отношений, в том числе некоторые, добавленные к существующим объектам.

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

Обновление (2/25/12): Когда я начал работать над новой промежуточной моделью, я вспомнил, что я изменил класс (представленное имя класса) для нескольких объектов из NSManagedObject в подкласс NSManagedObject, но не имел генерировал файлы классов. Я не подозревал, что это вызовет проблему, и, действительно, создание всех файлов классов не помогло бы исключение. Я просто хотел отметить это как другое изменение между моделями.

Выводы:

Это дикое предположение, но если число 36 объекта не случайно, кажется, что, когда «MyObject» пытается обвинить в «Object2» он не имеет действительного ссылки для таблицы и пытается загрузить номер таблицы -1, вызывая исключение. Однако тот факт, что простое присвоение [self object2] является успешным, не подрывает этого вывода.

Любые идеи?

ответ

2

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

Проблема:

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

Решение:

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

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

Мне все еще нужно заняться всеми остальными сущностями и попробуем этот подход, чтобы сделать остальное навалом, со всеми плановыми атрибутами и отношениями нетронутыми.

+0

Как вы сделали это, чтобы выбрать свою модель сопоставления? после отключения автоматической миграции? –

+0

@ JoãoNunes После отключения автоматической миграции он должен автоматически выбрать вашу модель сопоставления до тех пор, пока совпадают хеши источника и адресата. Они должны совпадать, если вы не изменили модель данных с момента создания модели сопоставления. К сожалению, иногда это не так, как указано здесь: (http://stackoverflow.com/questions/10894383/core-data-mapping-model-version-hashes-not-matching-to-source-model-version-hash). Включение режима «Отладка основных данных» Режим «Отладка» может помочь устранить проблемы с отображением моделей сопоставления. –

+0

Спасибо за подсказку. Я добавил debug для миграции, но все еще имею проблему. Я создал вопрос здесь: http://stackoverflow.com/questions/17464414/core-data-mapping-model-not-working-with-correct-hashes –

1

Ваши сообщения были полезны, когда я столкнулся с этой проблемой. Спасибо. [Вы уже сообщали об ошибке?]

Вот еще несколько экспериментальных результатов, но, увы, не очень хорошее решение.

  • Мое изменение схемы аналогичным образом добавило подтип объекта, который не имеет дополнительных атрибутов или отношений. Сообщение об ошибке совпадает с вашим, кроме границ [0 .. 19]. Это соответствует 20 типам сущностей, подтверждая вашу гипотезу. Как и в вашей ситуации, ошибка произошла при попытке получить доступ к свойству объекта после завершения миграции.

  • Добавление атрибута фиктивного типа и фиктивной самозависимости к новому типу объекта не предотвращает крах после миграции. (Тем не менее, я не испытывал с этим новым типом сущности как изменение только схемы, так как я ранее толкнул, что изменение схемы для альфа-тестеров.)

  • Я наблюдаю симптомы Z2_MYOBJECT колонки и Z_PRIMARYKEY.Z_MAX = -1 после успешной миграции на другие изменения схемы, поэтому они могут вообще не быть проблематичными. Значения -1 легко заменяются собственными максимальными значениями. Дополнительная колонка может использоваться во время миграции.

  • В моем случае супертип нового объекта имеет упорядоченное отношение-многие. В очень простом случае, когда весь хранилище данных содержит только один экземпляр объекта (экземпляр этого типа объекта без ссылок на исходящие отношения), миграция схемы преуспевает. Он имеет дополнительный столбец Z2_MYOBJECT и значения Z_PRIMARYKEY.Z_MAX = -1, и все же результирующий хранилище данных отлично работает при добавлении объектов оттуда.

  • Я попытался создать модель сопоставления, но не смог получить основные данные для ее применения. Отключение предполагаемого сопоставления только что привело к невозможности переноса данных Core Data вообще. Есть ли уловка? Должен ли я писать специальный код перехода для вызова модели сопоставления? Это Xcode 4.6.2, поэтому старшая ошибка давно ушла.

  • При использовании мерзавца катать модель данных код & назад или вперед, чтобы провести эксперимент, то, как представляется, необходимо (1) закрыть & вновь открыть проект Xcode и (2) сделать чистую сборку. В противном случае Xcode может обрушиться и/или оставить состояние смешения.

  • Экспериментально катиться назад, вы должны удалить каталог .momd/ или все приложения от целевой IOS симулятор/устройства (или развернуть приложение через ITunes или TestFlight) с переброски через Xcode не будет удалять устаревшие файлы (например, .mom и .omo определения модели данных), что, в свою очередь, позволяет приложениям выполнять легкие миграции, которые фактическое развернутое приложение не может сделать.

  • Сведения о сопоставлении сущности для использования для типа добавленной сущности, обратите внимание, что когда Core Data применяет модель сопоставления, она копирует объекты из старого хранилища данных в новый. Это не изменение таблиц на месте. Вы не хотите, чтобы он «пропускал» свойства (включая унаследованные свойства), если вы не хотите их отбрасывать.

  • Однако, поскольку изменение схемы добавило тип сущности, у этого объекта нет экземпляров для миграции, поэтому его пользовательские правила сопоставления моделей не имеют значения.

Так мне интересно, если что-то еще вызвало ваши аварии, чтобы остановить, как оставшиеся экспериментальные .mom файлы или пользовательской миграцию кода. Помогло ли ваше обходное решение?

После 2 дней эксперимента я решил, что на этот раз мои альфа-тестеры будут жить без переноса данных. К счастью, это произошло без производственных клиентов. Но это не дает мне уверенности в Core Data.

+0

Благодарим вас за добавленную информацию. Пройдя мимо проблемы, отмеченной здесь, в моем ответе я столкнулся с еще одной повторяющейся проблемой, которая привлекла мое внимание: (http: // stackoverflow.ком/вопросы/10894383/ядро-данные-картографирования-модель-версия-хэш-не-соответствие истока-модель-версия-хэш). Ответ на этот вопрос не разрешил мне эту проблему, поэтому я добавил ему щедрость, но не получил ответа. Я не сообщал об ошибке, так как я надеялся посетить сессию Core Data на местной конференции Cocoa в прошлом месяце и посмотреть, знают ли эксперты решение. К сожалению, я не смог присутствовать. –

+0

В общем, вам не нужно писать собственный код перехода, однако есть несколько вещей, которые могут помешать работе модели сопоставления. Один из них рассматривается в вопросе, на который я ссылался в своем вышеприведенном комментарии. Вы хотите проверить хеши в модели сопоставления в сравнении с файлами исходных данных и активной версией модели. Ответьте на этот вопрос, чтобы узнать, как включить отладку Core Data, если вы еще этого не сделали: http://stackoverflow.com/questions/12835950/debug-core-data-migration-to-compare-hash-values –

1

У меня был такой же вид NSRangeException после добавления базовой модели модели данных при доступе к любому экземпляру определенного объекта после автоматической облегченной миграции. В моем случае диапазон соответствовал количеству объектов в моей модели.

Сгенерирована модель отображения с Xcode 4.6 (4H127) с использованием File > New > File..., а затем выберите Core Data > Mapping Model. Это вызвало сбой в (г) превратиться в -[NSSymbolicExpression length]: unrecognized selector sent to instance...

Решения

Проблема в моем случае был то, что мое лицо, вызвавшее сбой имело отношения с именем size, которая является зарезервированным словом, перечисленным в компании Apple Predicate Programming Guide , Изучение модели отображения показал, что зарезервированное слово было капитализированы в стоимостном выражении для отношений:

FUNCTION($manager, "destinationInstancesForEntityMappingNamed:sourceInstances:" , "PNSizeOptionToPNSizeOption", $source.SIZE)

Я нашел решение в Core Data Model Versioning and Data Migration Programming Guide:

Зарезервированные слова в выражениях пользовательских значений : Если вы используете пользовательское значение , вы должны избежать зарезервированных слов, таких как SIZE, FIRST и LAST, используя # (например, $ source. # Size).

К сожалению, алгоритм Xcode для создания модели отображения не признавала зарезервированное слово, и я должен был изменить ключевой путь Выражение в инспекторе отношений Mapping для $source.#size. Это решило проблему. Я предполагаю, что модель предполагаемого сопоставления основных данных столкнулась с аналогичной проблемой во время легкой миграции.

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