18

次のようなinitWithContentsOfURL:コンストラクターを使用してNSManagedObjectModelモデルをロードしています。

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyDocument" withExtension:@"momd"];
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

ただし、これではモデルの最新/現在のバージョンにしかアクセスできません。同じmomdファイルで以前のバージョンをロードすることは可能ですか?どうやって?

4

5 に答える 5

36

実際には、次の方法で古いバージョンをロードできます。

- (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が関係する厄介な手動移行の状況から抜け出しました。高低を検索しましたが、これはどこにも見つかりませんでした。

于 2012-09-12T14:59:46.097 に答える
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: 初期化子を使用してから versionIdentifiers プロパティを検査するか、 isConfiguration:compatibleWithStoreMetadata: インスタンス メソッドを使用して互換性を判断する必要がある特定のバージョン識別子を持つものを見つけると思います。

于 2012-09-05T15:46:57.057 に答える
2

@Schoob が提供するソリューションをカテゴリにしました

@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
于 2014-05-29T23:09:21.283 に答える
-2

いいえ、これが可能であるとは予見されていません。NSManagedObjectModel 私はドキュメントからそれを推測し、プロパティについて話していると言っていますversionIdentifiers

この値は、マージされたモデルを作成するために結合されたモデルを特定するのに役立つデバッグ ヒントとして使用することを目的としています。

そのため、プログラム ロジックに以前のモデル バージョンを使用することは想定されていないようです。

于 2012-06-23T11:45:48.647 に答える