Подтвердить что ты не робот

Легкая миграция NSPsistentDocument

Я пытаюсь сделать легкую миграцию хранилища 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;
}

(Благодаря Джеффу Ламаршу за идею: http://iphonedevelopment.blogspot.com/2009/09/core-data-migration-problems.html)

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

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

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

Очевидно, что я делаю что-то не так, но я понятия не имею, что. Любая помощь была бы наиболее оценена...

Update:

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

- (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.

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

Перейти к этому обновлению

Еще одно доказательство того, что это серьезная ошибка с компилятором Data Model Compiler (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. Образцовое приложение, используемое в Радаре, все еще сбой.

(Примечание: вы не можете установить 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 должны делать с обновленными объектами и атрибутами

Через Evadne Wu на Twitter:

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

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

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

(.MM файлы являются двоичными.)

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

4b9b3361

Ответ 1

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

name == $name

в

name == $name

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

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

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

Ответ 2

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

Ответ 3

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

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

Ответ 4

Это может быть связано с проблемой, с которой я столкнулся с использованием запросов на выборку, когда iOS5 впервые вышел в бета-версии. Это вызвало предупреждение о сбое и привело к сбою приложения при запуске. Я не использовал запрос на выборку, поэтому я удалил его, и все сработало нормально: Предупреждение о базовых данных: "Информация о хеш-версии недоступна для всех моделей"