2012-03-13 44 views
4

我需要在嘗試設置值之前檢查NSEntityDescription項是否存在。我有一個來自JSON的數據字典,不想嘗試設置我的對象中不存在的鍵。檢查是否存在NSEntityDescription項

Appointment *appointmentObject = [NSEntityDescription insertNewObjectForEntityForName:@"Appointments" inManagedObjectContext:[[DataManager sharedInstance] managedObjectContext]]; 
for (id key in dict) { 
    // Check if the key exists here before setting the value so we don't error out. 
     [appointmentObject setValue:[dict objectForKey:key] forKey:key]; 
} 

回答

12

你不應該檢查選擇器。想象一下名爲entitymanagedObjectContext的密鑰。 NSManagedObject類肯定會對這些選擇器作出響應,但如果您嘗試將錯誤分配給這些選擇器,最好的情況是您的代碼會立即崩潰。運氣少一點,像這樣會破壞整個核心數據文件和所有用戶數據。

NSEntityDescription有一個名爲attributesByName的方法,它返回一個包含屬性名稱和相應的NSAttributeDescriptions的字典。所以這些鍵基本上都是你可以使用的所有屬性。

像這樣的東西應該工作:

Appointment *appointmentObject = [NSEntityDescription insertNewObjectForEntityForName:@"Appointments" inManagedObjectContext:[[DataManager sharedInstance] managedObjectContext]]; 
NSArray *availableKeys = [[appointmentObject.entity attributesByName] allKeys]; 
for (id key in dict) { 
    if ([availableKeys containsObject:key]) { 
     // Check if the key exists here before setting the value so we don't error out. 
     [appointmentObject setValue:[dict objectForKey:key] forKey:key]; 
    } 
} 
+0

你說得很好!由於我依靠JSON響應來提供密鑰,因此它們很可能具有響應普通選擇器的密鑰。 – Bot 2012-03-13 20:52:15

+1

爲什麼有人不喜歡這個? – Bot 2012-03-13 21:56:18

-1

我想你問你是否要檢查約會對象是否響應屬性。在這種情況下:

if([appointmentObject respondsToSelector:NSSelectorFromString(key)])... 

getter等價物是propertyName。 setter等價物是setPropertyName。

+0

這是一樣的'respondsToSelector:@selector(鍵)'?如果是的話,我嘗試了這一點,但沒有奏效。 – Bot 2012-03-13 20:09:43

+0

是字符串還是其他類型的對象的關鍵?我認爲這是一個字符串。 – Gobot 2012-03-13 20:12:57

+0

所有'@ property'都是'NSString',除了'NSNumber'外,其他錯誤是當它遇到不在'Appointment'類中的鍵時。 – Bot 2012-03-13 20:19:21

5

檢查這一點,

BOOL hasFoo = [[myObject.entity propertiesByName] objectForKey:@"foo"] != nil;

+1

太棒了!非常優雅的方式來檢查。 – mpemburn 2013-04-08 01:24:03