我正在使用initWithContentsOfURL:构造函数加载NSManagedObjectModel模型,如下所示:
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyDocument" withExtension:@"momd"];
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
然而,这只能让我访问模型的最新/当前版本。是否可以使用相同的 momd 文件加载以前的版本?如何?
答案 0 :(得分:34)
实际上您可以使用以下内容加载旧版本
- (NSManagedObjectModel *)managedObjectModelForVersion:(NSString *)version
{
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:[NSString stringWithFormat:@"AppModel.momd/AppModel %@",version] withExtension:@"mom"];
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return model;
}
只需将AppModel替换为您的型号名称。
我正在使用它来摆脱涉及iCloud的粘性手动迁移情况。搜索高低,无法在任何地方找到它。
答案 1 :(得分:4)
如果您只想加载与特定现有商店兼容的型号版本,请尝试:
NSError *error = nil;
NSDictionary *storeMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType
URL:storeURL
error:&error];
NSManagedObjectModel *oldManagedObjectModel = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:[NSBundle mainBundle]]
forStoreMetadata:storeMetadata];
请注意,如果您对数据模型版本使用XCode版本标识符,则可以通过商店元数据字典中的NSStoreModelVersionIdentifiersKey条目访问持久性商店的当前版本标识符。
就加载特定的任意版本而言,mom文件通常位于应用程序包中的momd目录下,因此您可以使用NSFileManager枚举它们。我相信要找到一个具有特定版本标识符的文件,您必须使用NSManagedObjectModel的initWithContentsOfURL:initializer,然后检查versionIdentifiers属性,或使用isConfiguration:compatibleWithStoreMetadata:instance方法来确定兼容性。
答案 2 :(得分:2)
将@Schoob提供的solution分类,因为他们摇滚。
@interface NSManagedObjectModel (version)
+ (NSManagedObjectModel *)modelFromBundle:(NSBundle *)bundle name:(NSString *)modelName version:(NSString *)version;
@end
@implementation NSManagedObjectModel (version)
+ (NSManagedObjectModel *)modelFromBundle:(NSBundle *)bundle name:(NSString *)modelName version:(NSString *)version
{
if(!bundle)
bundle = [NSBundle mainBundle];
NSString *resource = [[modelName stringByAppendingPathExtension:@"momd"] stringByAppendingPathComponent:version];
NSURL *modelURL = [bundle URLForResource:resource withExtension:@"mom"];
NSAssert(modelURL,@"Unable to find MOM - %@",resource);
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSAssert(model,@"Unable to load MOM at URL- %@",modelURL);
return model;
}
@end
答案 3 :(得分:0)
Swift版本。替换文件名。
import CoreData
extension NSManagedObjectModel
{
class func model(forVersion version: Int) -> NSManagedObjectModel?
{
if let fileUrl = Bundle.main.url(forResource: "Model.momd/Model \(version)", withExtension: "mom")
{
return NSManagedObjectModel(contentsOf: fileUrl)
}
return .none
}
}
答案 4 :(得分:-2)
不,没有预见到这是可能的。我从NSManagedObjectModel
documentation推断出来,在那里讨论财产versionIdentifiers
:
此值旨在用作调试提示,以帮助您确定组合以创建合并模型的模型。
因此,您似乎不应该将以前的模型版本用于您的程序逻辑。