【问题标题】:NSDictionaray dictionaryWithObjectsAndKeys adding NULL valueNSDictionaray dictionaryWithObjectsAndKeys 添加 NULL 值
【发布时间】:2011-06-23 21:31:15
【问题描述】:

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

【问题讨论】:

    标签: objective-c nsdictionary nsnull


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      如果您有很多对象,创建 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
      

      NSNull 加法

      @implementation NSNull (NullAddition)
      
      + (id)nullWhenNil:(id)obj {
      
          return (obj ? obj : [self null]);
      
      }
      
      @end
      

      祝你好运!

      【讨论】:

      • 作为 NSNull 类别的替代方案,您还可以创建一个宏:#define NSNullIfNil(v) (v ? v : [NSNull null])
      【解决方案3】:

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

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

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

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

      【讨论】:

        【解决方案4】:

        我遇到了类似的问题,谷歌带我到这里。我需要在字典中添加一些 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 更改为您想要的任何内容。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-11-22
          • 1970-01-01
          • 2021-09-07
          • 1970-01-01
          • 1970-01-01
          • 2018-01-25
          • 2017-07-03
          • 1970-01-01
          相关资源
          最近更新 更多