У меня есть приложение Core Data на основе NSPersistentDocument, которое нацелено на 10,5 леопарда и выше. Я собираюсь выпустить обновление, которое вносит изменения в модель данных, и поэтому необходимо перенести существующие документы в новую модель. Изменения относительно просты, и я создал для них модель отображения. Обратите внимание, что я не пытаюсь выполнить автоматическую облегченную миграцию, у меня есть модель сопоставления (облегченная миграция не поддерживается на Leopard, но изменения в моей модели в любом случае исключают ее). В моем подклассе NSPersistentDocument я переопределяю -configurePersistentStoreCoordinatorForURL...
следующим образом:
- (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)url
ofType:(NSString *)fileType
modelConfiguration:(NSString *)configuration
storeOptions:(NSDictionary *)storeOptions
error:(NSError **)error
{
NSMutableDictionary *newOptions = (storeOptions ?
[NSMutableDictionary dictionaryWithDictionary:storeOptions] :
[NSMutableDictionary dictionary]);
[newOptions setObject:(id)kCFBooleanTrue forKey:NSMigratePersistentStoresAutomaticallyOption];
return [super configurePersistentStoreCoordinatorForURL:url
ofType:fileType
modelConfiguration:configuration
storeOptions:newOptions
error:error];
}
Это прекрасно работает на 10.6 и 10.7. Однако на 10.5 вызов [super configurePersistentStore...]
вызывает исключение и завершается неудачей. Ошибка:
Error Domain=NSCocoaErrorDomain Code=134020 UserInfo=0x15812d70 "The model configuration used to open the store is incompatible with the one that was used to create the store."
Если я вместо этого инициирую миграцию вручную, используя этот код:
NSArray *bundles = [NSArray arrayWithObject:[NSBundle mainBundle]];
NSManagedObjectModel *sourceModel = [NSManagedObjectModel mergedModelFromBundles:bundles forStoreMetadata:sourceMetadata];
NSManagedObjectModel *destinationModel = [psc managedObjectModel];
NSMappingModel *mappingModel = [NSMappingModel mappingModelFromBundles:bundles forSourceModel:sourceModel destinationModel:destinationModel];
NSMigrationManager *migrationManager = [[[NSMigrationManager alloc] initWithSourceModel:sourceModel destinationModel:destinationModel] autorelease];
BOOL migrationSuccessful = [migrationManager migrateStoreFromURL:backupURL
type:NSXMLStoreType
options:storeOptions
withMappingModel:mappingModel
toDestinationURL:url
destinationType:NSXMLStoreType
destinationOptions:storeOptions
error:error];
return [psc addPersistentStoreWithType:NSXMLStoreType configuration:configuration URL:url options:storeOptions error:error] != nil;
миграция работает нормально. Тем не менее, я бы предпочел использовать автоматическую миграцию, если только по той причине, что это делает код чище. Кто-нибудь видел подобную проблему с автоматической миграцией, которая работает на 10.6+, но не на 10.5? Я догадываюсь, что это что-то довольно простое, например, встроенный код миграции по какой-то причине не может найти модель отображения, но я не могу понять, что это должно быть.