Запись пользовательского преобразователя значения
Платформа Основы обеспечивает несколько встроенных преобразователей значения. Вы создаете свои собственные преобразователи значения путем разделения на подклассы NSValueTransformer.
NSValueTransformer подкласс должен, как минимум, реализовать transformedValueClass, allowsReverseTransformation и transformedValue: методы. Если Ваш пользовательский преобразователь значения поддерживает обратные трансформации, необходимо также реализовать reverseTransformedValue: метод.
Как пример, мы создадим NSValueTransformer подкласс, FahrenheitToCelsiusTransformer, это преобразовывает Температуры по Фаренгейту в Шкалу Цельсия. Этот преобразователь значения также обратим, в состоянии преобразовать температуры по шкале Цельсия назад в Шкалу Фаренгейта.
Объявление возвращенного класса значения
Подкласс преобразователя значения должен реализовать transformedValueClass метод класса. Этот метод возвращает класс объекта что transformedValue: возвраты метода.
FahrenheitToCelsiusTransformer класс возвращает NSNumber, как показано в Перечислении 1.
Перечисление 1 Фаренгейт к Цельсия transformedValueClass реализация
+ (Class)transformedValueClass |
{ |
return [NSNumber class]; |
} |
Разрешение обратных трансформаций
NSValueTransformer подклассы должны также реализовать allowsReverseTransformation метод класса. Реализация подкласса должна возвратиться YES если преобразователь значения обратим.
Фаренгейт к преобразователю значения Цельсия обратим, таким образом, allowsReverseTransformation возвраты реализации YES, как показано в Перечислении 2.
Перечисление 2 Фаренгейт к Цельсия allowsReverseTransformation реализация
+ (BOOL)allowsReverseTransformation |
{ |
return YES; |
} |
Преобразование значения
transformedValue: метод реализует трансформацию фактического значения. Это передало объект преобразовать и возвращает результат трансформации. Результатом должен быть экземпляр класса, возвращенного transformedValueClass.
Для максимальной гибкости, реализации transformedValue: должен быть подготовлен обработать множество различных классов как значение. Фаренгейт к преобразователю Цельсия может обработать значения обоих NSString и NSNumber классы, при помощи floatValue метод для преобразования значения в скаляр.
Результат, возвращающийся, когда значение nil зависит от того, что преобразователь значения пытается сделать. Фаренгейт к реализации Цельсия transformedValue:, показанный в Перечислении 3, возвратах nil в этом случае.
Перечисление 3 Фаренгейт к Цельсия transformedValue реализация
- (id)transformedValue:(id)value |
{ |
float fahrenheitInputValue; |
float celsiusOutputValue; |
if (value == nil) return nil; |
// Attempt to get a reasonable value from the |
// value object. |
if ([value respondsToSelector: @selector(floatValue)]) { |
// handles NSString and NSNumber |
fahrenheitInputValue = [value floatValue]; |
} else { |
[NSException raise: NSInternalInconsistencyException |
format: @"Value (%@) does not respond to -floatValue.", |
[value class]]; |
} |
// calculate Celsius value |
celsiusOutputValue = (5.0/9.0)*(fahrenheitInputValue - 32.0); |
return [NSNumber numberWithFloat: celsiusOutputValue]; |
} |
Реверс, преобразовывающий значение
Если NSValueTransformer разделите трансформации реверса поддержек на подклассы, это должно реализовать reverseTransformedValue: метод.
Необходимо соблюдать осторожность при реализации обратимых преобразователей значения, чтобы гарантировать, что реверсирование не приводит к потере точности. Во многих случаях, передавая результат transformedValue: к reverseTransformedValue: должен возвратить объект с тем же значением как исходный объект.
Фаренгейт к реализации Цельсия reverseTransformedValue: показан в Перечислении 4. Единственная значительная разница между этим и transformedValue: реализация является температурной формулой преобразования.
Перечисление 4 Фаренгейт к Цельсия reverseTransformedValue реализация
- (id)reverseTransformedValue:(id)value |
{ |
float celsiusInputValue; |
float fahrenheitOutputValue; |
if (value == nil) return nil; |
// Attempt to get a reasonable value from the |
// value object. |
if ([value respondsToSelector: @selector(floatValue)]) { |
// handles NSString and NSNumber |
celsiusInputValue = [value floatValue]; |
} else { |
[NSException raise: NSInternalInconsistencyException |
format: @"Value (%@) does not respond to -floatValue.", |
[value class]]; |
} |
// calculate Fahrenheit value |
fahrenheitOutputValue = ((9.0/5.0) * celsiusInputValue) + 32.0; |
return [NSNumber numberWithDouble: fahrenheitOutputValue]; |
} |