检查NSMutableDictionary的键是否为nil

时间:2015-12-29 14:58:08

标签: ios objective-c

如果从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}

如何以正确的方式检查?

3 个答案:

答案 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是单身,因此==可以。