10

ほとんどの (私が見たすべての) Core Data チュートリアルでは、@"MyEntityClass"ハードコーディングされた次のコード スニペットを使用します。

NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"MyEntityClass"];

NSStringFromClass()エンティティ名として使用しても安全ですか?

NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:NSStringFromClass([MyEntityClass class])];

これにより、リファクタリングなどの処理がはるかに簡単になります。特に、Xcode にNSManagedObjectサブクラスを作成させているためです。今まで見たことがなかったので質問したので、何か抜けているかもしれません。

4

1 に答える 1

16

はい、モデルでエンティティのクラスが設定されている場合、そのコードは問題ありません。MyEntityClass

エンティティ クラスに、エンティティ名を返すクラス メソッドを与えることを好みます。

+ (NSString *)entityName {
    return NSStringFromClass(self);
}

次のように呼び出します。

NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:[MyEntityClass entityName]];

このように、モデル内のエンティティ名を変更せずにクラス名を変更したい場合は、クラス メソッドを変更するだけです。

+ (NSString *)entityName {
    return @"NewEntityName";
}

なぜ私はそれをするのですか?ええと、実体のより良い名前を決めるかもしれません。クラス名を変更しても既存の Core Data 永続ストアとの互換性は損なわれませんが、モデル ファイル内のエンティティ名を変更すると互換性が損なわれます。クラス名とentityNameメソッドは変更できますが、モデル内のエンティティ名は変更しないので、移行について心配する必要はありません。(軽量移行はエンティティの名前変更をサポートするため、どちらにしてもそれほど大きな問題ではありません。)

entityNameさらに進んで、実行時にマネージド オブジェクト モデルからメソッドにエンティティ名を実際に検索させることもできます。アプリケーション デリゲートに、マネージド オブジェクト モデルを返すメッセージがあるとします。

+ (NSString *)entityName {
    static NSString *name;
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        NSString *myName = NSStringFromClass(self);
        NSManagedObjectModel *model = [(AppDelegate *)[UIApplication delegate] managedObjectModel];
        for (NSEntityDescription *description in model.entities) {
            if ([description.managedObjectClassName isEqualToString:myName]) {
                name = description.name;
                break;
            }
        }
        [NSException raise:NSInvalidArgumentException
            format:@"no entity found that uses %@ as its class", myName];
    });
    return name;
}

明らかに、本当にこれを行いたい場合は、dispatch_onceブロックの内容をヘルパー メソッドに分解する必要があります。おそらく、アプリのデリゲート (またはモデルを取得する場所) で行います。

于 2012-12-27T05:13:24.767 に答える