Запись пользовательского преобразователя значения
Платформа Основы обеспечивает несколько встроенных преобразователей значения. Вы создаете свои собственные преобразователи значения путем разделения на подклассы 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]; |
} |