如果从Json Data获得NSMutableDictionary
NSMutableDictionary *returnedDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
我知道在某些情况下,此密钥returnedDict[@"data"][@"weather"][day][@"tides"]
为NSNull
。所以我得到-[NSNull objectForKeyedSubscript:]
所以我根据这个答案How to check if an NSDictionary or NSMutableDictionary contains a key?尝试检查它是否为零。
if (returnedDict[@"data"][@"weather"][day][@"tides"]){ some code }
和
if (returnedDict[@"data"][@"weather"][day][@"tides"]!=[NSNull null]){ some code}
不会避免运行{some code}
如何以正确的方式检查?
答案 0 :(得分:2)
所以你的问题是:
您的服务器可能会返回null
以指示对象不存在。 NSJSONSerialization
会将null
转换为NSNull
的实例。从理论上讲,这意味着您需要检查result[a][b][c]
是否是字典,如果是,result[a]
是否是字典等等,这是重复和错误的,而不是result[a][b]
。易发?
最简单的方法可能是从字典中删除值为NSNull
的任何键,这样下次你要求的值就会得到一个普通的nil
,这是安全的根据通常的复合消息传递规则发送消息?
NSJSONSerialization
不会为你做那件事但事后很容易补充:
@interface NSDictionary(RemoveNullValues)
- (NSDictionary *)ty_collectionWithoutNullValues;
@end
@interface NSArray(RemoveNullValues)
- (NSArray *)ty_collectionWithoutNullValues;
@end
[...]
@implementation NSDictionary(RemoveNullValues)
- (NSDictionary *)ty_collectionWithoutNullValues {
NSMutableDictionary *reducedDictionary = [self mutableCopy];
// remove any keys for which NSNull is the direct value
NSArray *keysEvaluatingToNull = [self allKeysForObject:[NSNull null]];
[reducedDictionary removeObjectsForKeys:keysEvaluatingToNull];
// ask any child dictionaries to do the same; note that it's safe
// to mutate reducedDictionary in this array because allKeys is a
// copy property; what you're iterating is not reducedDictionary
// but a snapshot of its keys when the array first began
for (id key in [reducedDictionary allKeys]) {
id child = reducedDictionary[key];
if ([child respondsToSelector:@selector(ty_collectionWithoutNullValues)]) {
reducedDictionary[key] = [child ty_collectionWithoutNullValues];
}
}
return [reducedDictionary copy];
}
@end
@implementation NSArray(RemoveNullValues)
- (NSArray *)ty_collectionWithoutNullValues {
NSMutableArray *reducedArray = [NSMutableArray array];
for (id child in self) {
if ([child isKindOfClass:[NSNull class]]) continue;
if ([child respondsToSelector:@selector(ty_collectionWithoutNullValues)]) {
[reducedArray addObject:[child ty_collectionWithoutNullValues]];
} else {
[reducedArray addObject:child];
}
}
return [reducedArray copy];
}
@end
答案 1 :(得分:0)
使用
if(![returnedDict[@"data"][@"weather"][day][@"tides"] isKindOfClass:[NSNull class]]) { some code }
答案 2 :(得分:0)
您必须将此答案与已接受的答案和一起阅读问题Is there NSMutableDictionary literal syntax to remove an element?
如果您使用文字语法访问该元素(即不),则可以悄悄删除所有NSNull
并返回nil
。 em>使用objectForKey:
)将以下内容添加到您的应用程序中:
@implementation NSDictionary (ClobberNSNull)
- (id) objectForKeyedSubscript:(id<NSCopying>)key
{
id result = [self objectForKey:key];
return result == NSNull.null ? nil : result;
}
@end
现在使用语法:
dictionary[key]
如果匹配的对象是NSNull
,那么将返回nil
,就像密钥不存在一样。
有警告,请参阅相关问题,您需要确定此方法是否适合您的情况。但这很简单。
HTH
注意:在有人发表评论之前,NSNull
是单身,因此==
可以。