Создание объектов NSDictionary может быть сложным, если у вас много объектов, поэтому, если они равны нулю, их не следует включать в словарь.
Для меня NSNull - такая же большая проблема, как и ее решение. При создании объектов NSDictionary для использования в других объектах вы можете пойти двумя путями, когда имеете дело со значениями nil . Либо вы добавляете объекты NSNull в свой словарь, а затем проверяете значения NSNull при чтении значений. Это делает красивый код на этапе создания, но он становится грязным при считывании значений. Ex. Вы должны проверить все ключи в словаре, или некоторые гарантированно не равны нулю? И если значение NSNull не отфильтровано, оно обязано делать исключения при попытке отправить объектные сообщения.
Второй способ - просто не добавлять значения NSNull в словарь. Это удобно при чтении NSDictionary, так как [ someDictionary objectForKey: someKey ] просто возвращает nil, когда ключ не установлен. Такой подход делает это довольно легко при чтении значений, но он действительно должен быть грязным кодом при создании. Ex. Создание NSMutableDictionary, проверка на nil перед добавлением значений и, наконец, возвращение неизменяемой копии?
Решение
Для меня решение состояло в том, чтобы создать две категории, что, по сути, облегчает как создание, так и чтение.
Когда вы создаете NSDictionary, вы просто оборачиваете возможные значения-ноль, как это
[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
Удачи!