Как обычно использовать KVC для обновления полей?

Скажем, у меня есть следующий класс Objective-C:

@interface Foo {
     int someNumber;
     NSString *someString;
}

и по причинам, которые я не буду здесь обсуждать, я хочу использовать KVC для общего обновления значений этих переменных:

[f setValue:object forKey:@"someNumber"];

or

[f setValue:object forKey:@"someString"];`

Если object является строкой, и я обновляю переменную someNumber, кажется, мне нужно знать, как использовать NSNumberFormatter для получения NSNumber, а затем Cocoa автоматически преобразует это в int внутри setValue:forKey:.

Есть ли способ избежать этого пользовательского кода и заставить Cocoa вывести преобразование в int из строки, или мне нужно каждый раз ловить эту ситуацию и обрабатывать ее самостоятельно?


person drewh    schedule 18.11.2008    source источник


Ответы (3)


Вы должны выполнить преобразование самостоятельно с помощью средства форматирования чисел, это дает вам более точный контроль, чем все, что фреймворк может счесть подходящим. Также, вероятно, не рекомендуется использовать один экземпляр объекта для обновления значений ваших переменных. Более подходящим образом вы можете выполнить обновление на основе класса объекта (при условии, что вы не сохраняете в id, запрашивая среду выполнения относительно класса объекта с помощью object_getClassName. Дополнительная информация доступна в Objective-C 2.0 Справочник по времени выполнения Но в целом вы, скорее всего, найдете ошибки в своем коде в результате того, что будете делать что-то подобным образом.

person wisequark    schedule 18.11.2008

Следующий код должен обрабатывать преобразование автоматически, если параметр object является членом класса, реализующего integerValue.

Обратите внимание, что и NSNumber, и NSString реализуют этот метод.

- (void)setValue:(id)object forKey:(NSString *)key
{
    if ([key isEqual:@"someNumber"])
    {
        someNumber = [object integerValue];
    }
    //...
}

изменить: (примечание): вы можете не писать метод самостоятельно, используя свойства target-c. Реализация setValue:forKey: по умолчанию сделает всю работу за вас, если вы создадите свойства для someNumber и someString.

person e.James    schedule 18.11.2008

Я с wisequark на этом. Я думаю, что setValue:forKey: эквивалентен прямому вызову установщика. Если бы у вас был метод:

- (void)setSomeValue:(NSInteger)aValue

Вы не ожидаете, что сможете передать NSString и надеяться, что метод сможет это понять.

Другими словами, значение ключа дает вам доступ к свойству, и это свойство имеет тип. При использовании KVC числа просто заворачиваются в объект NSNumber, так что существует только один метод setValue:forKey:. Поэтому я говорю, что ответственность за упаковку строки в объект NSNumber всегда лежит на вызывающем коде.

В такие времена я сожалею, что Cocoa Touch не поддерживает привязки. Привязки позволят вам добавить преобразователь значений, который может автоматически обрабатывать преобразование из строки в число. Возможно в следующей версии!

person Alex    schedule 18.11.2008