2013-11-13 4 views
4

У меня возникла очень любопытная проблема, связанная с миграцией CoreData.iOS 7 - Миграция CoreData - Xcode 5

В принципе, у меня есть 2 объекта, где в одном из них я добавляю свойство, а в другом я изменяю тип свойства из NSString в NSArray (Transformable). До сих пор, так хорошо, он работает хорошо, были проведены тесты и целостность данных была неповрежденной после миграции.

Проблема возникает, если я запускаю тот же самый код на Xcode 5 (я не знаю, связано ли это с iOS SDK 7.0 или Xcode 5), но миграция запускает и развращает данные.

В итоге я создал простой проект, чтобы продемонстрировать, что происходит. https://dl.dropboxusercontent.com/u/1393279/CoreDataMigration.zip

Шаги по воспроизведению является: - На Xcode 5 (IOS SDK 7.0), вы можете использовать тренажер -

1 - Открыть проект "BeforeMigration" и выполнить. См. Журналы и созданные данные, никаких проблем до сих пор;

2 - Остановить проект;

3 - Открыть проект «После миграции», выполнить и запустить.

4 - Смотрите, что миграция выполняется, но данные повреждается:

2013-11-13 12:22:29.778 CoreDataMigration[7223:70b] CoreData: error: exception during fetchRowForObjectID: * -[NSKeyedUnarchiver initForReadingWithData:]: incomprehensible archive (0x43, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0) with userInfo of (null) 2013-11-13 12:22:29.782 CoreDataMigration[7223:70b] Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '** -[NSKeyedUnarchiver initForReadingWithData:]: incomprehensible archive (0x43, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)'

AFAIK, непонятный архив означает испорченные данные по CoreData.

Что трудно понять, так это то, что тот же самый точный код работал раньше, поэтому, если это логическая проблема, это должно произойти на Xcode 4.5. Я искал CoreData Diffs, но не нашел ничего подходящего.

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

+1

Что вы имеете в виду, вы изменили свойства к NSArray? Core Data не имеет типа массива. Как вы сохраняете данные и как вы переносите NSString в NSArray? –

+0

Извините, я перешел на трансформируемое – iDevzilla

+0

Я обнаружил, что проблема возникает, если я вызываю «backupSourceStoreAtURL». Кажется, я больше не могу переименовать файл .sqlite. Не знаю, почему. – iDevzilla

ответ

3

В прошивке 7, режим журнального по умолчанию основных данных SQLite магазина были изменены на Write-Ahead Logging (WAL), чтобы повысить надежность, производительность, и параллелизм.

Проблема заключалась в том, что я не перемещал файл -wal с основными данными. Один из способов исправить это, чтобы удалить -wal с помощью:

NSDictionary *options = @{NSSQLitePragmasOption:@{@"journal_mode":@"DELETE"}}; 

Или перемещение -wal с:

- (NSPersistentStore *)migratePersistentStore:(NSPersistentStore *)store toURL:(NSURL *)URL options:(NSDictionary *)options withType:(NSString *)storeType error:(NSError **)error 
2

Попробуйте использовать moGenerator link и попробуйте выполнить следующие действия:

  • использование Моген (или MOGenerator) для автоматической генерации вам основные классов модели данных сущностей из модели с каждой сборкой (использовать выделенные цели до сборки для этого);
  • всегда включает моделирование версий при создании новой модели данных;
  • при создании новой версии модели данных:

    1. добавить новую модель данных версии - назовем это «новая версия»; установите свой идентификатор базовой модели данных в следующую желаемую версию (например: 1.1 или 2.0 и т. Д.). Это логичный идентификатор версии, совместимый с разработчиками, - это не заставляет Core Data обрабатывать эту версию по-разному, если к ней не будут сделаны критические изменения;

    2. переименовать то, что использовалось для текущей версии модели, добавив свой Идентификатор версии к имени. Например, если это «MyDataModel.xcdatamodel», у которого его Идентификатор версии установлен в 1.1 - переименуйте его в «MyDataModel_1.1.xcdatamodel»;

    3. переименуйте новую добавленную версию в простое имя модели, например «MyDataModel.xcdatamodel», и сделайте ее текущей версией.Таким образом, вы всегда сохраняете имя текущей версии модели одинаково, и ваши скрипты активации/сборки MOGen не будут меняться (в случае, если вы используете MOGen - и вы должны);

    4. при необходимости изменить текущую модель;

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

    6. очистить свой продукт;

    7. Восстановите свой продукт;

    8. проверить его.

Лучших практики Андрей Корнич

Смежные вопросы