Objective-C - 将类属性与 json 字典数据对齐

Posted

技术标签:

【中文标题】Objective-C - 将类属性与 json 字典数据对齐【英文标题】:Objective-C - aligning class properties with json dictionary data 【发布时间】:2012-12-29 10:57:23 【问题描述】:

我对 Objective-C 比较陌生(主要使用 cocoa/apple 基础框架),但我是一名长期的 C++ 程序员,所以我将首先解释我想要完成的工作;我的方法很可能不是最好的,所以我很想听听任何关于不同方法的建议。

我有一个 json 格式的文本文件,只是做了这个简单的例子:

"section1" : 
    "director" : "Sample Name 1",
    "writers" : 
        "name" : "Example Name 1",
        "name" : "Example Name 2",
    ,
,

我有一个类,它的属性要与这个文件中的数据匹配,因为我打算解析这个文件并将一些值存储在这个类的一个实例中。我的类标题大致如下所示:

@interface SongData : NSObject
@property (nonatomic, copy) NSString *director;
@property (nonatomic, copy) NSArray *writers;
@end

所以我试图找到最干净、有点“数据驱动”的方式来将此 json 数据存储到正确的属性中。基本上我想要一种方法来循环遍历数据的 json“字典”,并以某种方式使用“键”与我的类中的正确属性匹配并将值分配给该属性。我第一次破解它,我创建了一个字典,其中“键”是在 json 数据中查找正确数据的实际键,“值”将是指向正确类属性的指针。有点像这样:

NSDictionary *descriptionDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:
                                       director, @"name",
                                       writers, @"writers",
                                       nil];

然后想法是遍历json数据(存储在另一个NSDictionary中),使用我的“descriptionDictionary”中的每个键在json数据中查找适当的值,然后使用描述的匹配“值”基于相同键的字典(我希望它是指向实际类属性的指针?)并将该属性值设置为 json 数据中的值。也许一个例子会让它更清楚:-)。让我们假设“jsonDictionary”是解析我的 json 数据的结果,并且我已经在 section1 中,因此构成 jsonData NSDictionary 的键和构成我的 descriptionDictionary NSDictionary 的键之间应该有 1-1 匹配:

[descriptionDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) 
    value = [jsonDictionary objectForKey:propertyName];
];

现在“值”在技术上将指向我的类属性之一,我想为其分配相关的 json 数据(即,director = @“Sample Name 1”)。我知道我正在做的事情有问题(我意识到我可能不能只是取消引用指向随机类属性的指针并为其分配一个未知类型的任意对象,希望它们都匹配:-) 但希望我的示例至少说明了我正在尝试做的事情,以便有人可以告诉我更好的方法。

【问题讨论】:

【参考方案1】:

看看KVC(来源:http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueCoding/Articles/BasicPrinciples.html

使用键值编码设置属性值

方法setValue:forKey:设置指定key的值, 相对于接收者,相对于提供的值。默认 setValue:forKey 的实现:自动解开 NSValue 表示标量和结构并将它们分配给 财产。有关详细信息,请参阅“标量和结构支持” 包装和展开语义。

如果指定的key不存在,则向接收者发送一个 setValue:forUndefinedKey: 消息。的默认实现 setValue:forUndefinedKey: 引发 NSUndefinedKeyException;然而, 子类可以重写此方法以自定义处理请求 方式。

setValue:forKeyPath: 方法的行为类似,但它 能够处理密钥路径以及单个密钥。

最后,setValuesForKeysWithDictionary:设置属性 接收器具有指定字典中的值,使用 用于识别属性的字典键。默认实现 调用 setValue:forKey: 对于每个键值对,用 nil 代替 根据需要提供 NSNull 对象。

您应该考虑的另一个问题是,当 尝试将非对象属性设置为 nil 值。在这个 在这种情况下,接收方会向自己发送一个 setNilValueForKey: 消息。这 setNilValueForKey 的默认实现:引发 NSInvalidArgumentException。您的应用程序可以覆盖此方法 替换默认值或标记值,然后调用 setValue:forKey: 使用新值。

只要您的类属性与 JSON 字段同名,您就可以使用 setValuesForKeysWithDictionary: 并传入 JSON 根字典。

对于名称不同的键/属性,您可以简单地覆盖 setValue:forUndefinedKey: 并自己设置适当的属性。

最后,JSON 中的值与属性中的类型不同。例如 NSURL 将是一个 NSString 代替。在这里您可以简单地检查传递参数的类,如果它与 IVAR 不匹配,则进行转换。

【讨论】:

正是我想要的,谢谢!刚刚运行了一个快速测试,它运行良好。 NSDictionary *descriptionData = [jsonData objectForKey:@"description"]; if (descriptionData != nil) [self setValuesForKeysWithDictionary:descriptionData];

以上是关于Objective-C - 将类属性与 json 字典数据对齐的主要内容,如果未能解决你的问题,请参考以下文章

idea中的插件,可以快速将类中的属性转换成Json字符串

Objective-c 解析 JSON 响应

Objective-C 实例变量与属性的区别

带有指针的属性与objective-c中的属性之间的差异

Objective-C——属性与成员变量辨析

objective-C学习笔记数据成员:属性与实例变量