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】:

nilNULL 实际上都等于 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;

这个值将是NSStringnil,你不应该自己检查它的NSNull, NULL。

【讨论】:

以上是关于TouchJSON,处理 NSNull的主要内容,如果未能解决你的问题,请参考以下文章

(转)NSNULL

NSNull floatValue intValue 找不到指定方法解决方式

TouchJSON的简单使用

使用 TouchJson 序列化字典的问题

ios JSON解析常见错误

使 NSNull 符合 NilLiteralConvertible