2012-12-27 10 views
9

Çoğu (hepsi gördüğüm) Çekirdek Veri öğreticiler ile aşağıdaki kod parçacığını kullanın @"MyEntityClass" kodlanmış içinde:NSStringFromClass ([MyEntityClass sınıfı]) güvenli bir Çekirdek Veri Varlığı adı oluşturur mu?

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

bir varlık Adı olarak NSStringFromClass() kullanmak güvenli midir?

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

Bu üstlenmeden ve benzeri ilgili başa easer olması yolunmuş. Özellikle Xcode'um NSManagedObject alt sınıflarımı oluşturduğumdan beri. Bunu sordum çünkü daha önce hiç görmedim, belki de bir şeyleri özlüyorum.

cevap

14

Evet, bu kod gayet iyi, , öğenizin sınıfının modeli MyEntityClass olarak ayarlanmışsa.

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

ve böyle diyoruz:

ben varlık sınıfı varlık adını döndüren bir sınıf yöntemi vermeyi tercih

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

Bu şekilde, ben sınıfını değiştirmek istiyorsanız modeldeki varlık adını değiştirmeden ad, yalnızca sınıf yönteminde değişiklik yapabilirim:

Bunu neden yapmalıyım? Eh, varlığın daha iyi bir ismine karar verebilirim. Sınıf adının değiştirilmesi, var olan bir Çekirdek Verili kalıcı mağaza ile uyumluluğu bozmaz, ancak model dosyasındaki varlık adını değiştirir. Sınıf adını ve entityName yöntemini değiştirebilir, ancak modelde model adını değiştirmeden bırakabilirim ve sonra göç konusunda endişelenmem gerekmiyor. (Hafif geçiş, yeniden adlandırılmış varlıkları destekler, dolayısıyla her iki şekilde de bir anlaşma olmaz.)

Daha ileri gidebilir ve yönetilen nesne modelinden çalışma zamanında varlık adını entityName yöntemine bakabilirsiniz. Varsayalım Başvurunuz temsilci yönetilen nesne modelini döndüren bir mesajı var: Eğer gerçekten bunu yapmak istiyorsanız, uygulamanızda muhtemelen bir yardımcı yöntem haline dispatch_once bloğun içeriğini çarpanlarına gerekir Açıkçası

+ (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; 
} 

temsilci (veya modeli nereden alırsanız alın).

+0

Ek arama kodunu eklemek için o ana kadar gitmek istemiyorsanız, bu onaylamayı "entityName:" için herhangi bir dahili erişimden önce ekleyebilirsiniz. 'NSAssert (context.persistentStoreCoordinator.managedObjectModel.entitiesByName [[‌ self entityName]]! = Nil, @"% @ adıyla var olmayan modelde bulunamadı. Sınıf adınız varlık adınızla aynı mı? ", [Self entityName ]); 'Modelinizin varlık adınız sınıfınızın adıyla eşleşmiyorsa, bu size çalışma zamanında bir hata verecektir. –

+0

Bu durumda, her otomatik oluşturulan nesnenin kategorisine kod eklemeniz gerekir? Sadece bu işlevi eklemek için sınıflar için yeni bir dosya oluşturmaktan endişe ediyorum. –

+0

@VitaliK NSManagedObject öğesine bir kategori ekleyebilirsiniz, ancak bunu yaparsanız, bunu 'genelAdı' olarak adlandırmayın. İsim çarpışmalarından kaçınmak için 'Vitali_entityName' gibi bir önek kullanın. –

İlgili konular