NSDictionaray dictionaryWithObjectsAndKeys添加NULL值

pro*_*ock 12 objective-c nsdictionary nsnull

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

Ven*_*MKO 23

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


Tre*_*kow 5

如果你有很多对象,那么创建NSDictionary对象可以是精简的,如果它们是nil,则不应该包含在字典中.

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

第二种方法是不将NSNull值添加到字典中.这在阅读NSDictionary时很方便,因为[ someDictionary objectForKey:someKey ]在没有设置密钥时只返回nil.这种方法在读取值时非常容易,但实际上它必然会在创建时出现混乱的代码.防爆.创建一个NSMutableDictionary,在添加值之前检查nil,最后返回一个不可变的副本?

对我来说,解决方案是创建两个类别,在本质上使创建和阅读结束都很容易.

在创建NSDictionary时,您只需将这些可能的值包装成这样

[NSDictionary dictionaryWithObjectsAndKeysIngoringNull:
 [NSNull nullWhenNil:val1], @"value1",
 [NSNull nullWhenNil:val2], @"value2",
 ...
 nil];
Run Code Online (Sandbox Code Playgroud)

此代码几乎与第一种方法一样简单,但在读取值时更容易实现.

类别如下(适用于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
Run Code Online (Sandbox Code Playgroud)

NSNull补充

@implementation NSNull (NullAddition)

+ (id)nullWhenNil:(id)obj {

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

}

@end
Run Code Online (Sandbox Code Playgroud)

祝好运!