NSManagedObject - 如何获取属性的类型
Posted
技术标签:
【中文标题】NSManagedObject - 如何获取属性的类型【英文标题】:NSManagedObject - How to get the type of the property 【发布时间】:2010-12-13 01:00:06 【问题描述】:我正在尝试将 json 字符串直接解析为托管对象。 json 字符串包含所有字符串,但我的 Entity 有 Date 对象。
如果这是我的 json 字符串
"name":"John",
"dob": "12/12/2008",
etc...
这是我的实体 Person:
name : NSString
dob: Date
etc...
我想通过遍历 Json dict 的键来直接解析该 json,并将值设置为我实体的匹配键:
Person *aPerson = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:managedObjectContext];
NSArray *keys = [jsonDict allKeys];
for (NSString *key in keys)
[aPerson setValue:[jsonDict valueForKey:key] forKey:key];
这仅在我的所有实体的属性都是 NSString 时才有效。
如何获取实体属性的类型/类以便能够设置各种类型?
例如。 如果键 = @"dob" 如何获取 aPerson.dob 的类型/类?
所以我的代码看起来像:
Person *aPerson = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:managedObjectContext];
NSArray *keys = [jsonDict allKeys];
for (NSString *key in keys)
if([[aPerson objectForKey:key] isKindOfClass:[NSDate class]])
// Create an NSDate object
else
[aPerson setValue:[jsonDict valueForKey:key] forKey:key];
谢谢
更新:
好的,我尝试使用 isKindOfClass,结果如下:
// for key = @"name"
// aPerson.name is NSString
[[aPerson valueForKey:key] isKindOfClass:[NSString class]] => TRUE
[[aPerson valueForKey:key] isKindOfClass:[NSObject class]] => TRUE
// for key = @"age"
// aPerson.age is NSNumber
[[aPerson valueForKey:key] isKindOfClass:[NSNumber class]] => TRUE
[[aPerson valueForKey:key] isKindOfClass:[NSObject class]] => TRUE
// for key = @"dob"
// aPerson.dob is NSDate
[[aPerson valueForKey:key] isKindOfClass:[NSDate class]] => FALSE
[[aPerson valueForKey:key] isKindOfClass:[NSObject class]] => FALSE
怎么样? @dynamic dob 和 NSDate,是 notOfClass NSDate!
请告诉我我错过了什么!
【问题讨论】:
除了我下面的答案之外,您可以使用 if ([key isEqualToString:"dob"]) // 创建 NSDate 对象... 感谢 Rog,但我希望使解析更加动态,只获取实体属性的类型,而不必知道密钥的名称,即。 “多布” 是的,所有公平点。这是未经测试的使用if ([[movie valueForKey:key] isKindOfClass:[NSDate class]])
我试过了,但由于某种原因,我的 NSDate 属性没有被识别为 kindOfClass NSDate!正如更新中发布的那样。感谢您的帮助。
返回的 dob 是什么? NSNull 还是别的什么?
【参考方案1】:
我知道,这是一个迟到的答案,但是当我今天正在寻找一个好的解决方案时...... 这是我现在使用的:
NSEntityDescription * myEntity = [object entity];
NSDictionary * attributes = [myEntity attributesByName];
if ([[[attributes objectForKey:key] attributeValueClassName] isEqualToString:@"NSDate"])
// this type is NSDate
希望这会有所帮助:)
【讨论】:
【参考方案2】:您可以将您的 JSON 字符串转换为 NSDate,然后将其分配给您的 NSManagedObject,或者您可以在您的 Person 类中创建一个自定义设置器,它接受一个 NSString 并返回 NSDate。这是一个例子:
- (NSDate*)convertStringToDate:(NSString*)dateString
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// this is imporant - we set our input date format to match our input string
// if format doesn't match you'll get nil from your string, so be careful
[dateFormatter setDateFormat:@"d MMMM yyyy"];
NSDate *dateFromString = [dateFormatter dateFromString:dateString];
[dateFormatter release];
return dateFromString;
【讨论】:
感谢 Rog,但我仍然需要知道何时应该将字符串转换为日期。我需要知道 person.xx 中 xx 的类型,才能动态创建它们的对象。例如。 person.dob、person.loginDate 等...如果我能分辨出它们都是 NSDate 属性,那么我可以从该 json 字符串中创建一个 NSDate。 不一定。您可以传递 (id) 而不是 NSString,然后在您的 setter 中使用isKindOfClass
进行条件评估。
试过了,问题是它创建了一个无限循环,因为我需要通过它的设置器 self.dob 来设置 dob,它是一个动态属性。
一切都好,我能够实现动态属性的设置器,现在它工作正常。谢谢你的帮助。我已经发布了解决方案。【参考方案3】:
非常感谢 Rog,让我朝着正确的方向前进,我最终覆盖了我的 setter,如下所示:
-(void)setDob:(id)value
[self willAccessValueForKey:@"dob"];
if ([value isKindOfClass:[NSString class]])
[self setPrimitiveValue:[DateFormatter dateFromString:value] forKey:@"dob"];
else
[self setPrimitiveValue:value forKey:@"dob"];
[self didChangeValueForKey:@"dob"];
现在一切都很好,而不是 1000 行代码解析,全部在 3 内完成! 不错!
【讨论】:
不错的解决方案,干净整洁。感谢发布!以上是关于NSManagedObject - 如何获取属性的类型的主要内容,如果未能解决你的问题,请参考以下文章
获取 NSManagedObject 的属性作为 NSDictionary
如何计算/迭代 NSManagedObject 具有的所有属性?
Swift 从实体(核心数据)获取特定的 NSManagedObject