我的基于 Core Data 文档的应用程序(仅限 10.5)的数据模型位于
框架,因此使用核心数据映射自动升级架构
模型似乎不起作用。看来 Core Data 机器
当他们找不到合适的数据模型或映射模型时
不在应用程序的主包中。所以,而不是使用自动
迁移,我正在手动运行迁移configurePersistentStoreCoordinatorForURL:ofType:...
在我的NSPersistenDocument
子类(下面的代码)。我迁移持久的
存储到一个临时文件,然后覆盖现有文件,如果
迁移成功。该文档然后显示一个错误
消息“此文档的文件已被另一个应用程序更改
因为你打开或保存了它。”当我尝试保存时。就像其他人一样
列表已经指出,这是由于我修改了
文档的文件“在其背后”。我尝试更新文档的
文件修改日期,如下所示,但随后出现错误对话框
带有消息“文档“test.ovproj”的位置不能
确定。”当我尝试保存时。我不太确定这是什么原因
错误,但用一个不必要的消息(在这种情况下)换另一个
不是我想要的。
任何人都可以提供一些指导吗?有没有办法手动升级
不触发其中之一的文档持久存储的架构
这些(在这种情况下是不必要的)警告?
用于升级我的子类中的数据存储的代码-configurePersistentStoreCoordinatorForURL:ofType:...
:
if(upgradeNeeded) {
NSManagedObjectModel *sourceModel = [NSManagedObjectModel mergedModelFromBundles:VUIModelBundles() orStoreMetadata:meta];
if(sourceModel == nil) {
*error = [NSError errorWithDomain:VUIErrorDomainn ode:VUICoreDataErrorCode localizedReason:BWLocalizedString(@"Unable to find original data model for project.")];
return NO;
}
NSManagedObjectModel *destinationModel = [self managedObjectModel];
NSMigrationManager *migrationManager = [[NSMigrationManager alloc] initWithSourceModel:sourceModel destinationModel:destinationModel];
NSMappingModel *mappingModel = [NSMappingModel mappingModelFromBundles:VUIModelBundles() forSourceModel:sourceModel destinationModel:destinationModel];
if(mappingModel == nil) {
*error = [NSError errorWithDomain:VUIErrorDomain code:VUICoreDataErrorCode localizedReason:BWLocalizedString(@"Unable to find mapping model to convert project to most recent project format.")];
return NO;
}
@try {
//move file to backup
NSAssert([url isFileURL], @"store url is not a file URL");
NSString *tmpPath = [NSString tempFilePath];
id storeType = [meta objectForKey:NSStoreTypeKey];
if(![migrationManager migrateStoreFromURL:url
type:storeType
options:storeOptions
withMappingModel:mappingModel
toDestinationURL:[NSURLfileURLWithPath:tmpPath]
destinationType:storeType
destinationOptions:storeOptions
error:error]) {
return NO;
} else {
//replace old with new
if(![[NSFileManager defaultManager] removeItemAtPath:[url path] error:error] ||
![[NSFileManager defaultManager] moveItemAtPath:tmpPath toPath:[url path] error:error]) {
return NO;
}
// update document file modification date to prevent warning (#292)
NSDate *newModificationDate = [[[NSFileManager defaultManager] fileAttributesAtPath:[url path] traverseLink:NO] bjectForKey:NSFileModificationDate];
[self setFileModificationDate:newModificationDate];
}
}
@finally {
[migrationManager release];
}
}
}
return [super configurePersistentStoreCoordinatorForURL:url ofType:fileType modelConfiguration:configuration storeOptions:storeOptions error:error];
最佳答案
我没有遇到过这种特殊情况,但我有一些猜测。首先,当你想切换文件时,不要使用 -removeItemAtPath: 和 -moveItemAtPath: ,而是使用 FSExchangeObjects() 函数。 NSDocument 使用 FSRefs 来跟踪文件,除非您使用 FSExchangeObjects(),否则它会意识到它正在查看一个完全不同的文件。
其次,您可以通过覆盖 -managedObjectModel 手动设置文档的托管对象模型,特别是使用 +mergedModelFromBundles: 方法从您的框架加载模型。根据文档,默认情况下它应该合并主包和所有链接框架中的任何模型,所以这应该只对动态加载的包是必要的。不知道为什么这对您不起作用,但我还没有尝试过。要找出要搜索的包,NSBundle 的 +bundleForClass: 方法是您的 friend 。
关于macos - 没有 "document changed"警告的手动核心数据架构迁移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/380076/