关于可可触摸:为什么UITextField上的valueForKey:会引发UITextInputTraits属性的异常?

Why does valueForKey: on a UITextField throws an exception for UITextInputTraits properties?

运行此:

1
2
3
4
5
6
7
8
9
@try
{
    NSLog(@"1. autocapitalizationType = %d", [self.textField autocapitalizationType]);
    NSLog(@"2. autocapitalizationType = %@", [self.textField valueForKey:@"autocapitalizationType"]);
}
@catch (NSException *exception)
{
    NSLog(@"3. %@", exception);
}

输出此:

1
2
1. autocapitalizationType = 0
3. [<UITextField 0x6c15df0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key autocapitalizationType.

我期待:

1
2
1. autocapitalizationType = 0
2. autocapitalizationType = 0

此异常仅在UITextInputTraits协议的一部分属性中发生。 可以通过valueForKey:访问具有clearButtonModeUITextField的常规属性。

那么,为什么不能通过键值编码访问UITextInputTraits属性?


如果您深入研究UIKit框架并打开UITextField.h,则会发现:

1
2
3
4
5
@interface UITextField : UIControl <UITextInput, NSCoding> {
  @private

    UITextInputTraits  *_traits;
    UITextInputTraits  *_nonAtomTraits;

您还将发现UITextField头文件中将clearButtonMode声明为@property,但是未将autocapitalizationType(以及其余的UITextInputTraits协议)声明为。

您和我看不到UITextField.m,所以我们真正能得出的结论是,Apple以与KVC不兼容的方式实现了UITextFieldUITextInputTraits协议。 大概某个地方的粘合代码会将[myTextField autocapitalizationType]转换为适当的值,但是发生的任何幕后魔术都无法达到valueForKey:的水平。


这是我的变通办法:对于实现textInputTraits方法的每个类,我都使用valueForKey:。 如果键是UITextInputTraits键,则在对象的textInputTraits而不是对象本身上调用valueForKey:

以下是实施细节:1、2和3。