objective c - Облегченная миграция NSPersistentDocument

Translate

Я пытаюсь выполнить облегченную миграцию хранилища SQLite в Core Data. Работа над Lion 10.7.3 с Xcode 4.3.1.

В моем подклассе NSPersistentDocument (AccountDocument) я переопределил метод, используемый для настройки координатора постоянного хранилища, чтобы он получил правильные параметры для миграции:

- (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)url ofType:(NSString *)fileType modelConfiguration:(NSString *)configuration storeOptions:(NSDictionary *)storeOptions error:(NSError **)error
{
    NSMutableDictionary *newStoreOptions;
    if (storeOptions == nil) {
        newStoreOptions = [NSMutableDictionary dictionary];
    }
    else {
        newStoreOptions = [storeOptions mutableCopy];
    }
    [newStoreOptions setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
    [newStoreOptions setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];

    BOOL result = [super configurePersistentStoreCoordinatorForURL:url ofType:fileType modelConfiguration:configuration storeOptions:newStoreOptions error:error];
    return result;
}

(Спасибо Малкольму Кроуфорду за этот совет:http://homepage.mac.com/mmalc/CocoaExamples/controllers.html)

Когда я запускаю приложение, оно не работает в реализации NSPersistentDocument-managedObjectModel:

* thread #1: tid = 0x2703, 0x00007fff931d9350 libobjc.A.dylib`objc_msgSend_vtable13 + 16, stop reason = EXC_BAD_ACCESS (code=13, address=0x0)
    frame #0: 0x00007fff931d9350 libobjc.A.dylib`objc_msgSend_vtable13 + 16
    frame #1: 0x00007fff8935e975 CoreData`-[NSKnownKeysDictionary1 _setValues:retain:] + 197
    frame #2: 0x00007fff8935f288 CoreData`_newReadModelFromBytes + 648
    frame #3: 0x00007fff8935b93e CoreData`+[NSManagedObjectModel(_NSManagedObjectModelPrivateMethods) _newModelFromOptimizedEncoding:error:] + 9310
    frame #4: 0x00007fff89359451 CoreData`-[NSManagedObjectModel(_NSManagedObjectModelPrivateMethods) initWithContentsOfOptimizedURL:] + 305
    frame #5: 0x00007fff89358d7b CoreData`-[NSManagedObjectModel initWithContentsOfURL:] + 443
    frame #6: 0x00007fff893e9519 CoreData`+[NSManagedObjectModel mergedModelFromBundles:] + 377
    frame #7: 0x00007fff8ded7037 AppKit`-[NSPersistentDocument managedObjectModel] + 301
    frame #8: 0x00007fff8ded70b3 AppKit`-[NSPersistentDocument managedObjectContext] + 75
    frame #9: 0x00007fff8ded6e3f AppKit`-[NSPersistentDocument _persistentStoreCoordinator] + 18
    frame #10: 0x00007fff8ded6b5d AppKit`-[NSPersistentDocument configurePersistentStoreCoordinatorForURL:ofType:modelConfiguration:storeOptions:error:] + 51
    frame #11: 0x0000000100003193 BeanCounter`-[AccountDocument configurePersistentStoreCoordinatorForURL:ofType:modelConfiguration:storeOptions:error:] + 419 at AccountDocument.m:298

Судя по документации, реализация по умолчанию выглядит примерно так:

- (id)managedObjectModel
{
    NSManagedObjectModel *result = [NSManagedObjectModel mergedModelFromBundles:nil];
    return result;
}

Итак, чтобы немного отладить проблему, я переопределил этот метод следующим образом:

- (id)managedObjectModel
{
    NSBundle *bundle = [NSBundle mainBundle];
    NSURL *url = [bundle URLForResource:@"AccountDocument2" withExtension:@"momd"];
    NSManagedObjectModel *result = [[[NSManagedObjectModel alloc] initWithContentsOfURL:url] autorelease];  
    return result;
}

(Спасибо Jeff LaMarche за идею:http://iphonedevelopment.blogspot.com/2009/09/core-data-migration-problems.html)

И пакет, и URL-адрес указывают на места, которые я ожидаю (и я последовал совету Маркуса Зарры по очистке проекта, чтобы в пакете приложения не было случайных пакетов .mom или .momd:Использование mergedModelFromBundles: и управление версиями (CoreData)). Тем не менее, приложение продолжает вылетать при загрузке модели с URL-адреса.

Я проверил, что AccountDocument2.xcdatamodeld - это пакет, который имеет две модели для управления версиями: AccountDocument 2.xcdatamodel и (исходный) AccountDocument.xcdatamodel. Для всплывающего меню «Версия базовой модели данных» в свойствах файла задано значение «AccountDocument 2».

Единственное различие между двумя моделями заключается в том, что одна сущность имеет дополнительный (и необязательный) атрибут. Насколько я понимаю, это квалифицирует модель для облегченной миграции.

Очевидно, я здесь что-то делаю не так, но понятия не имею, что именно. Любая помощь будет очень признательна ...

Обновить:

По предложению Мартина (и проверке документации NSPersistentDocument) я попытался использовать этот код для средства доступа:

- (id)managedObjectModel
{
    static id sharedManagedObjectModel = nil;

    if (sharedManagedObjectModel == nil) {
        NSBundle *bundle = [NSBundle mainBundle];
        NSURL *url = [bundle URLForResource:@"AccountDocument2" withExtension:@"momd"];
        sharedManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:url];
    }

    return sharedManagedObjectModel;
}

По-прежнему происходит сбой…

Обновить

После некоторых предложений в Twitter я обновился до Xcode 4.3.2, но проблемы не исчезли.

ОБНОВЛЕНИЕ RAGE

Я только что создал пакет версионной модели (AccountDocument2.xcdatamodeld), используя Xcode 4.2 на Snow Leopard. После сборки и запуска приложения все работает должным образом.

Затем я вернул пакет файлов AccountDocument2.xcdatamodeld обратно в Lion и Xcode 4.3.2. Когда я создаю и запускаю приложение, оно продолжает вылетать при загрузке ресурса .momd. Да, детки, это означает, что виноваты Xcode 4.3.x и компилятор модели данных (MOMC). Я не вижу другого пути, кроме как делать все свои сборки на Snow Leopard.

Я не из тех, кто использует Xcode 4, но когда мы оказываемся в ситуации, когда инструментальная цепочка не может создать непрозрачный файл (.mom и .momd) из непрозрачной спецификации (.xcdatamodel и .xcdatamodeld), это довольно сложно Будьте оптимистичны по поводу состояния инструментов Mac и iOS. Нелепо, что основной компонент этих платформ ломается до такой степени, что я не могу создавать и запускать свое приложение на последней версии SDK и инструментов разработчика.

Это дошло до этого обновления

Еще одно доказательство того, что это серьезная ошибка компилятора модели данных (MOMC) в Xcode 4.3.2: если я скопирую пакет .momd из папки ресурсов, созданной Xcode 4.2, в свой проект и добавлю их в сборку как файлы копирования этап сборки, приложение работает нормально.

Я также провел несколько тестов, в которых я удалил правила проверки и значения по умолчанию для атрибутов различных сущностей (на основе предложения Маркуса ниже). Без изменений, компилятор по-прежнему создает недопустимый .momd. Я также попытался создать модель с версией, в которой НИЧЕГО не изменилось: скомпилированный .momd продолжал давать сбой. Итак, все, что у вас есть в ваших текущих моделях (и данных, которые они представляют), является источником проблемы.

Также обратите внимание: эта ошибка не изолирована от NSPersistentDocument (как я изначально думал, когда задавал этот вопрос). Я могу вызвать сбой приложения, просто используя[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL].

На данный момент я буду редактировать / управлять версиями своих моделей с помощью Xcode 4.2 на Snow Leopard и перемещать скомпилированные ресурсы в Xcode 4.3.2 на Lion. Если вы каким-либо образом используете Core Data, я предлагаю вам делать то же самое, пока эта ошибка не будет исправлена. Поверьте, вы потратите дни, пытаясь понять, что, черт возьми, происходит, если вы этого не сделаете.

Теперь, чтобы отправить радар…

Обновление радара

Я только что отправил этот радар:

http://www.openradar.me/11184500

Обновление "О, черт, должно быть, лев"

Я только что загрузил и установил инструменты Xcode 4.2 для Lion изhttp://developer.apple.com/downloads. Образец приложения, использованный в Radar, по-прежнему дает сбой.

(Примечание: вы не можете установить Xcode 4.2.1, потому что срок действия сертификата, используемого для подписи DeveloperTools.pkg, истек. Только Xcode 4.2 будет работать.)

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

Надеюсь, у вас есть копия Snow Leopard с Xcode 4.2, сидящая без дела:http://furbo.org/2012/03/28/vmware-for-developers/

WTF Do Fetch Requests имеет отношение к версионным сущностям и обновлению атрибутов

Через Эвадну Ву в Twitter:

https://twitter.com/#!/evadne/status/187625192342818818

И как она это сделала:

https://twitter.com/#!/evadne/status/187629091518816258

(Файлы .mom представляют собой двоичные списки.)

Корень проблемы - единственный запрос на выборку. Как это влияет на миграцию данных из одной модели в другую, предстоит выяснить инженеру Apple.

This question and all comments follow the "Attribution Required."

Все ответы

Translate

Скомпилированные ресурсы .momd могут быть загружены после того, как запрос на выборку "existingPartner" будет изменен с:

name == $name

кому:

name == $NAME

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

Взгляд Core Data на управление версиями состоит в том, что его интересуют только те особенности модели, которые влияют на постоянство.

Используйте силуCHOCKLOCKчтобы исправить ваши запросы на получение или полностью удалить их и полагаться наNSPredicates, созданные в коде.

Источник
Translate

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

Источник
Translate

Основываясь на вашей теории, что это проблема с MOMC, есть ли у вас какие-либо правила проверки в маме?

Я видел отчеты, в которых правила проверки не выдерживают испытания MOMC 4.x.

Источник
Z S
Translate

Это может быть отчасти связано с проблемой, с которой я столкнулся с использованием запросов на выборку, когда iOS5 только вышла в бета-версии. Это вызывало предупреждение о сборке и приводило к сбою приложения при запуске. На самом деле я не использовал запрос на выборку, поэтому удалил его, и все работало нормально:Предупреждение Core Data: «Хеш-информация о версии доступна не для всех моделей»

Источник
Leave a Reply
You must be logged in to post a answer.
Об авторе