1

我对 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”)。我知道我正在做的事情有问题(我意识到我可能不能只是取消引用指向随机类属性的指针并为其分配一个未知类型的任意对象,希望它们都匹配:-) 但希望我的示例至少说明了我正在尝试做的事情,以便有人可以告诉我更好的方法。

4

1 回答 1

3

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

使用键值编码设置属性值

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

如果指定的键不存在,则向接收者发送一个 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 不匹配,则进行转换。

于 2012-12-29T11:19:04.860 回答