12

我想用+[NSDictionary dictionaryWithObjectsAndKeys:]创建一个NSDictionary。我的一个键有一个字符串,但该字符串有时可以是. 如果字符串是,我之后放置的任何其他值键对都将被忽略,因为该列表过早终止。处理 a 中可能存在值的可能性的标准方法是什么?nilnilnilNSDictionary

4

4 回答 4

23

您需要检查字符串是否为空。如果是,请添加[NSNull null]而不是您的字符串。

于 2011-06-23T21:56:33.863 回答
6

如果你有很多对象,创建 NSDictionary 对象可能会很麻烦,如果它们是 nil,则不应包含在字典中。

对我来说,NSNull 是一个大问题,因为它是解决方案。在创建 NSDictionary 对象以供其他对象使用时,您可以通过两种方式处理nil值。要么将 NSNull 对象添加到字典中,然后在读取值时检查 NSNull 值。这在创建时会生成漂亮的代码,但是在读取值时会变得混乱。前任。您应该检查字典中的所有键,还是保证某些键不为零?如果没有过滤掉 NSNull 值,则在尝试发送对象消息时必然会出现异常。

第二种方法是不将 NSNull 值添加到字典中。这在读取 NSDictionary 时很方便,因为 [ someDictionary objectForKey: someKey ] 在未设置键时仅返回 nil。这种方法在读取值时变得非常容易,但在创建时确实必然是混乱的代码。前任。创建一个 NSMutableDictionary,在添加值之前检查 nil,最后返回一个不可变副本?

解决方案

对我来说,解决方案是创建两个类别,这在本质上使创建和阅读目的都变得容易。

创建 NSDictionary 时,您只需像这样包装可能的 nil 值

[NSDictionary dictionaryWithObjectsAndKeysIngoringNull:
 [NSNull nullWhenNil:val1], @"value1",
 [NSNull nullWhenNil:val2], @"value2",
 ...
 nil];

这段代码几乎和第一种方法一样简单,但它在读出值时变得更加容易。

类别如下(适用于启用 ARC 和非 ARC 代码):

NSDictionary 添加:

@implementation NSDictionary (NullAddition)

+ (id)dictionaryWithObjectsAndKeysIngnoringNull:(id)firstObject, ... {

    NSMutableArray* objects = [NSMutableArray array];
    NSMutableArray* keys = [NSMutableArray array];

    va_list args;
    va_start(args, firstObject);

    for (id object = firstObject; object; object = va_arg(args, id)) {

        id key = va_arg(args, id);

        if (!key)
            break;

        if (![object isKindOfClass:[NSNull class]]) {
            [objects addObject:object];
            [keys addObject:key];
        }

    }

    va_end(args);

    return [self dictionaryWithObjects:objects forKeys:keys];

}

@end

NSN空加

@implementation NSNull (NullAddition)

+ (id)nullWhenNil:(id)obj {

    return (obj ? obj : [self null]);

}

@end

祝你好运!

于 2012-08-27T07:41:05.840 回答
0

尝试向 an 中插入数据(键或值)NSDictionary将导致运行时错误。因此,您不必处理字典中的空数据。

'-[__NSCFDictionary setObject:forKey:]: attempt to insert nil value (key: Test)'

'-[__NSCFDictionary setObject:forKey:]: attempt to insert nil key'

但是,这意味着您有责任在将数据放入字典之前检查数据的有效性以防止崩溃。

于 2011-06-23T21:36:41.753 回答
0

我遇到了类似的问题,谷歌带我到这里。我需要在字典中添加一些 kv,其值可能为 nil。受 Trenskow 回答的启发,我修改了该函数以支持插入 nil 值,而不是像以前那样终止。

#define KV_END NSNull.null

NSDictionary *NSDictionaryOfKV(id firstKey, ...) {
    __auto_type dict = [NSMutableDictionary dictionary];

    va_list args;
    va_start(args, firstKey);

    for (id key = firstKey; key != NSNull.null; key = va_arg(args, id)) {
        id obj = va_arg(args, id);
        if (obj == NSNull.null) {
            break;
        }
        if (key) {
            dict[key] = obj;
        }
    }

    va_end(args);

    return dict.copy;
}
__auto_type value2 = nil;
__auto_type dict = NSDictionaryOfKV(key1, value1, key2, value2, key3, value3, KV_END);

你会得到

{
  key1: value1,
  key3: value3
}

您可以将 更改KV_END为您想要的任何内容。

当您的值是一个变量时,这很有意义,您可以按原样使用它,不需要包装它或 like value ?: NSNull.null

于 2020-03-18T09:38:12.687 回答