2012-12-27 2 views
9

ほとんど(すべては私が見てきた)コアデータチュートリアルをして、次のコードスニペットを使用し@"MyEntityClass"ハードコードされた中:NSStringFromClass([MyEntityClassクラス])は安全なCore Data Entity名を生成しますか?

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

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

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

これは、リファクタリングなどについて対処するために多くのeaserであることを縫い目。特に私はXcodeに私のNSManagedObjectサブクラスを作成させているからです。私はこれまでこれを見たことがないので尋ねるので、おそらく私は何かを逃しています。

答えて

14

エンティティのクラスがモデル内で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ブロックの内容を考慮する必要がありますデリゲート(またはモデルを入手した場所)。

+0

余分なルックアップコードを追加したくない場合は、このアサートを 'entityName:'への内部アクセスの前に追加することができます。 'NSAssert(context.persistentStoreCoordinator.managedObjectModel.entitiesByName [[self entityName]]!= nil、@"名前が%@のエンティティがモデルに見つかりません。クラス名はエンティティ名と同じですか? "、[self entityName ]); 'モデルのエンティティ名がクラス名と一致しないと、実行時にエラーが発生します。 –

+0

この場合、自動生成オブジェクトごとにカテゴリにコードを追加する必要がありますか?この関数だけを追加するクラスの新しいファイルを作成することを心配しています。 –

+0

@VitaliK 'NSManagedObject'にカテゴリを追加することもできますが、そうした場合、その名前はあまりにも一般的なので' entityName'という名前にはしないでください。 'Vitali_entityName'のような接頭辞を使って名前の衝突を避けてください。 –

関連する問題