iOS、JSON-RPC和NSJSONSerialization:处理空值

iOS、JSON-RPC和NSJSONSerialization:处理空值,ios,cocoa-touch,null,json-rpc,nsjsonserialization,Ios,Cocoa Touch,Null,Json Rpc,Nsjsonserialization,我使用JSON-RPC在iOS应用程序和服务器之间进行通信。服务器的某些返回值是可选的 考虑到我使用的技术组合,返回这些空值(如{“telephone”:null})还是完全忽略响应中的“telephone”元素更好 进一步解释我的问题: 它看起来不像JSON-RPC规范指定了与方法结果有多大关系(如果我错了,请纠正我),显然不发送loads null元素会提高性能并在一定程度上减少带宽。不过,我最感兴趣的是从iOS NSJSONSerialization的角度来看最好的方法。检查NSDicti

我使用JSON-RPC在iOS应用程序和服务器之间进行通信。服务器的某些返回值是可选的

考虑到我使用的技术组合,返回这些空值(如{“telephone”:null})还是完全忽略响应中的“telephone”元素更好

进一步解释我的问题:

它看起来不像JSON-RPC规范指定了与方法结果有多大关系(如果我错了,请纠正我),显然不发送loads null元素会提高性能并在一定程度上减少带宽。不过,我最感兴趣的是从iOS NSJSONSerialization的角度来看最好的方法。检查NSDictionary中是否存在键或现有键是否具有空值是否更容易/更好?

首先{“电话”:“null”}不是空值。有引号,所以实际上电话属性的字符串值带有文本“null”。服务器需要发送{“telephone”:null}-不带引号。 我会列出应用程序需要的所有相关属性作为响应,如果没有值,则将null作为一个值。然后,若key的值为NSNull,则可以轻松地签入从NSJSONSerialization获得的NSDictionary

if ([dictionaryValue isKindOfClass:[NSNull class]])
    myThink.myProperty = nil;

我使用的是一种完全不同的技术,肯定有点非正统,因为我的代码处理的是巨大的数据集,我真的很讨厌对每个值进行NSNull测试。我所做的是NSNull子类,所以在处理数据时,我可以测试它的数值是否为0,字符串长度是否为0,等等

@implementation NSNull (JSON)

- (NSUInteger)length { return 0; }

- (NSInteger)integerValue { return 0; };

- (CGFloat)floatValue { return 0; };

- (NSString *)description { return @"0(null)"; } // so I know it was NSNull in log messages

- (NSArray *)componentsSeparatedByString:(NSString *)separator { return @[]; }

- (id)objectForKey:(id)key { return nil; }

- (BOOL)boolValue { return NO; }

@end
编辑:我在一个电子商务发货应用程序中使用了完全相同的代码。实际上,有成千上万个对象被几十个不同的API返回——必须查看每个项目以确定它是否是
[NSNull null]
将是一场噩梦。我试着编写一个例程来整理结果,它会递归地查看字典和数组并重建对象,但它太复杂了


在任何情况下,我从未对这个解决方案有过任何问题。很明显,YMMV。

如果有人感兴趣,我已经将支票打包在函数中了

-(id)checkNull:(id)object{
    if([object isKindOfClass:[NSNull class]])return nil;
    else return object;
}

好地方。我已经相应地修改了这个问题,使用null而不是“null”。这是我决定采用的方法。NSNull只有一个实例,因此检查
value==[NSNull null]
有趣的方法会更快。我想你是在建议我返回{“telephone”:null},而不是什么都不返回?在我的例子中,我并不拥有事物的web端。也就是说,您永远不知道还有谁会使用您的web端代码,所以我个人会使用“标准”方法,而不是针对iOS对其进行调优-因此,是的,我会使用null-但在iOS端,这不会有什么区别,因为子类返回“”或0或其他任何内容。在我的iOS代码中,对于一个电话号码,如果它不是9位数字,那么它就不可用/不完整,因此我会要求用户在任何情况下输入一个新的号码。我选择不使用这种方法,因为我对像这样改变NSNull的行为有点犹豫。但是,INT_MIN或INT_MAX可能是更好的默认值。@EsbenBjerregaard请参见上面的编辑。最小值和最大值不合适-空值仅表示“不存在或未定义”,因此“inventory=null”与“inventory=0”在我的应用程序中是相同的,第一个意思(可能)是对象尚未库存,因此库存未定义。