TouchJSON,处理 NSNull
Posted
技术标签:
【中文标题】TouchJSON,处理 NSNull【英文标题】:TouchJSON, dealing with NSNull 【发布时间】:2011-04-19 13:16:16 【问题描述】:嗨 我正在使用 TouchJSON 反序列化一些 JSON。我过去一直在使用它,在那些情况下,我手动处理了 NSNull 的出现。我认为作者也必须处理这个问题,所以我再次这样做只是开销。然后我在文档中找到了这个:
在输出中避免 NSNull 值。
NSData *theJSONData = /* some JSON data */
CJSONDeserializer *theDeserializer = [CJSONDeserializer deserializer];
theDeserializer.nullObject = NULL;
NSError *theError = nil;
id theObject = [theDeserializer deserialize:theJSONData error:&theError];
按照我的理解,该类的用户可以将 C 风格的空指针传递给反序列化器,当它遇到 NSNull 时,它将插入传递给它的值(NULL)。所以稍后当我使用这些值时,我不会得到 NSNull,而是 NULL。
这看起来很奇怪,返回值是一个只能包含 Objects 的 NSDictionary,该值不应该默认为 'nil' 吗?
如果为 NULL,我可以检查这样的值吗?
if([jsonDataDict objectForKey:someKey] == NULL)
这样做似乎更合乎逻辑:
if(![jsonDataDict objectForKey:someKey])
更不用说允许传递 nil 但传递 NULL 会导致崩溃的所有情况。
或者我可以将“nil”传递给反序列化器吗?
这很大程度上源于我仍在为 nil、NULL、[NSNULL null] 苦苦挣扎,也许我没有看到使用 nil 的潜在警告。
【问题讨论】:
我在下面发表了评论,但为了这个问题的后代,NSDictionary 不能包含 nil 作为键或值。来自 Cocoa 文档:“键和值都不能为 nil;如果您需要在字典中表示空值,则应使用 NSNull。” 【参考方案1】:对于另一个 JSON 库,但有同样的问题,我在 NSDictionary 上创建了以下类别:
@implementation NSDictionary (Utility)
// in case of [NSNull null] values a nil is returned ...
- (id)objectForKeyNotNull:(id)key
id object = [self objectForKey:key];
if (object == [NSNull null])
return nil;
return object;
@end
每当我处理来自所述库的 JSON 数据时,我都会像这样检索值:
NSString *someString = [jsonDictionary objectForKeyNotNull:@"SomeString"];
这样,我的项目中的代码变得更加简洁,同时我不必考虑处理 [NSNull null] 值等问题。
【讨论】:
谢谢沃尔夫冈。如果您选择的 JSON 库不提供“nullObject”,我可以看到该类别的需求。每次您必须访问您的 +15 属性模型实体时,处理 NSNull 都是一团糟:) 这是一个很好的方法(事实上我在自己的应用程序中也是这样做的)。这样做的好处是您仍然可以检查字典中是否存在具有空值的键;将 TouchJSON 的nullObject
设置为 nil,您无法区分空值和缺失键。
键值编码将为您在集合中的 NSNull 和 nil 之间进行转换。 developer.apple.com/library/ios/documentation/Cocoa/Conceptual/…【参考方案2】:
nil
和 NULL
实际上都等于 0,因此在实践中它们是可以互换的。但你是对的,为了保持一致性,TouchJSON 的文档应该使用 theDeserializer.nullObject = nil
而不是 NULL
。
现在,当您这样做时,您的第二个谓词实际上可以正常工作:
if (![jsonDataDict objectForKey:someKey])
因为当您将nullObject
设置为nil
(或NULL
)时,TouchJSON 会忽略字典中的键。当字典中不存在该键时,NSDictionary 返回 nil,它为零,因此您的 if 条件按预期工作。
如果您不将 nullObject
指定为 nil
,则可以改为检查 null,如下所示:
if ([jsonDataDict objectForKey:someKey] == [NSNull null])
【讨论】:
谢谢,这很好地回答了它,只要我能始终如一地期望返回一个 nil 值我会没事的。【参考方案3】:有处理它的库。其中一个是 Swift 中的 SwiftyJSON,另一个是 Objective-C 中的 NSTEasyJSON。 使用这个库 (NSTEasyJSON) 将很容易处理此类问题。在你的情况下,你可以检查你需要的值:
NSTEasyJSON *JSON = [NSTEasyJSON withData:JSONData];
NSString *someValue = JSON[someKey].string;
这个值将是NSString
或nil
,你不应该自己检查它的NSNull, NULL。
【讨论】:
以上是关于TouchJSON,处理 NSNull的主要内容,如果未能解决你的问题,请参考以下文章