Безопасная подписка на NSDictionary
С синтаксисом литералов можно использовать словарь NSDictionary *, подобный этому, чтобы получить objectForKey
NSDictionary * dictionary;
id object = dictionary[key];
Но если тип словаря имеет тип ID, и вы пытаетесь написать
id dictionary;
id object = dictionary[key];
Это будет работать до тех пор, пока ваш словарь не станет действительно словарём, иначе он зависнет.
Решением для этого было бы иметь метод
-(id)safeObject:(id)object forKey:(id)aKey {
if (![object isKindOfClass:[NSDictionary class]]) {
return nil;
}
return [object objectForKeyedSubscript:aKey];
}
Так что теперь, когда я называю это так
id dictionary;
id object = [self safeObject:dictionary forKey:key];
Это не потерпит крах. Но проблема с этим в том, что если мне нужно углубиться, например, во вложенный словарь
id object = dictionary[key1][subKey1][subsubKey1];
Это действительно удобно писать с буквальным синтаксисом со старым синтаксисом, это было бы что-то вроде
id mainObject = [self safeObject:dictionary forKey:key1];
id subObject = [self safeObject:mainObject forKey:subKey1];
id object = [self safeObject:subObject forKey:subsubKey1];
Так что не так много читабельно. Я хочу иметь это решение с новым литеральным синтаксисом, возможно ли это?
1 ответ
Вы могли бы использовать valueForKeyPath
например,
id dictionary = @{@"key":@{@"subkey" : @{ @"subsubkey" : @"value"}}};
id object = [self safeObject:dictionary];
id value = [object valueForKeyPath:@"key.subkey.subsubkey"];
Также немного измените safeObject только для проверки, является ли это словарь,
- (id)safeObject:(id)object {
if (![object isKindOfClass:[NSDictionary class]]) {
return nil;
}
return object;
}
Надеюсь, это поможет, это то, что вы ищете?