如果您有很多对象,创建 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
祝你好运!