Почему valueForKey: на UITextField генерируется исключение для свойств UITextInputTraits?
Запуск:
@try
{
NSLog(@"1. autocapitalizationType = %d", [self.textField autocapitalizationType]);
NSLog(@"2. autocapitalizationType = %@", [self.textField valueForKey:@"autocapitalizationType"]);
}
@catch (NSException *exception)
{
NSLog(@"3. %@", exception);
}
Выводит следующее:
1. autocapitalizationType = 0
3. [<UITextField 0x6c15df0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key autocapitalizationType.
Я ожидал:
1. autocapitalizationType = 0
2. autocapitalizationType = 0
Это исключение происходит только со свойствами, которые являются частью протокола UITextInputTraits
. Регулярные свойства a UITextField
такие, что clearButtonMode
можно получить через valueForKey:
.
Итак, почему вы не можете получить доступ к свойствам UITextInputTraits
с ключом-значением?
Ответы
Ответ 1
Если вы вникаете в структуру UIKit и открываете UITextField.h
, вы найдете:
@interface UITextField : UIControl <UITextInput, NSCoding> {
@private
UITextInputTraits *_traits;
UITextInputTraits *_nonAtomTraits;
Вы также обнаружите, что clearButtonMode
объявлен как @property
в заголовочном файле UITextField, но это autocapitalizationType
(и остальная часть протокола UITextInputTraits
) не являются.
Мы с вами не видим UITextField.m
, поэтому мы можем заключить, что Apple внедрила протокол UITextField
UITextInputTraits
таким образом, чтобы не соответствовать требованиям KVC. Предположительно, код клея где-то преобразует [myTextField autocapitalizationType]
в соответствующее значение, но все, что происходит за кадром, останавливается до valueForKey:
.
Ответ 2
Вот мой обход: я swizzled valueForKey:
для каждого класса, реализующего метод textInputTraits
. Если ключ является ключом UITextInputTraits, тогда вызов valueForKey:
на объект textInputTraits
вместо самого объекта.
Вот подробности реализации: 1, 2 и 3.