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 и двете сочат към местата, които очаквам (и аз последвах съвета на Marcus Zarra за почистване на проекта, така че в пакета за кандидатстване да няма бездомни пакети .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 от папката Resource, създадена от 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

Oh Crap It Must Be Lion Update

Току-що изтеглих и инсталирах Xcode 4.2 for Lion tools от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 имат връзка с актуализирането на версиите на обекти и атрибути

Чрез Evadne Wu в 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 относно версирането е, че се интересува само от характеристиките на модела, които влияят на постоянството.

Използвайте силата наЧАКОВза да коригирате вашите заявки за извличане или да ги изтриете напълно и да разчитатеNSPredicates, създадени в код.

източник
Translate

Мисля, че трябва да съхранявате управлявания обектен модел в променлива на екземпляр. Връщате автоматично издаден обект, който вероятно причинява лошия достъп.

източник
Translate

Въз основа на вашата теория, че това е проблем с MOMC, имате ли някакви правила за валидиране при майката?

Виждал съм доклади, в които правилата за валидиране не оцеляват 4.x MOMC.

източник
Z S
Translate

Това може да е донякъде свързано с проблем, който имах при използването на Fetch Requests, когато iOS5 излезе за първи път в бета версия. Това причинява предупреждение за компилация и ще срине приложението при стартиране. Всъщност не използвах заявката за извличане, затова я премахнах и всичко работи добре:Предупреждение за основните данни: „Хеш информация за версията не е налична за всички модели“

източник
Leave a Reply
You must be logged in to post a answer.
За автора