NSKeyValueCoding
NSKeyValueCoding
键值编码,简写为KVC。提供一种通过字符串来访问类中的属性和成员变量的方法,并可以借助运算符进行计算。
NSUndefinedKeyException
当键值编码操作失败时会引发NSUndefinedKeyException(值:NSUnknownKeyException)异常。
NSKeyValueOperator
typedef NSString * NSKeyValueOperator NS_TYPED_ENUM;
定义了NSKeyValueOperator为NSString *类型的枚举;
NSKeyValueOperator有如下几种类型:
-
NSAverageKeyValueOperator
avg:平均值计算,比如:@avg.age -
NSCountKeyValueOperator
count:数量统计,比如:@count。除此之外的操作类型都需要一个右侧keypath。 -
NSDistinctUnionOfArraysKeyValueOperator
distinctUnionOfArrays:获取嵌套数组中不同的值,结果合并到同一数组,比如:@distinctUnionOfArrays.age -
NSDistinctUnionOfObjectsKeyValueOperator
distinctUnionOfObjects:获取数组中不同的值,比如:@distinctUnionOfObjects.age -
NSDistinctUnionOfSetsKeyValueOperator
distinctUnionOfSets:获取嵌套集合(或元素为数组)中不同的值,结果合并到同一集合 -
NSMaximumKeyValueOperator
max:distinctUnionOfObjects:获取最大值 -
NSMinimumKeyValueOperator
min:获取最小值 -
NSSumKeyValueOperator
sum:获取总数 -
NSUnionOfArraysKeyValueOperator
unionOfArrays:获取嵌套数组中的值,结果合并到同一数组 -
NSUnionOfObjectsKeyValueOperator
unionOfObjects:获取数组中的值 -
NSUnionOfSetsKeyValueOperator
unionOfSets:获取嵌套集合(或元素为数组)中的值

NSObject(NSKeyValueCoding)
@property (class, readonly) BOOL accessInstanceVariablesDirectly
如果-valueForKey:,-setValue:forKey:,-mutableArrayValueForKey:,-storedValueForKey:,-takeStoredValue:forKey:,和-takvalue:forKey:可以直接操作实例变量发送到接收类的实例,则返回YES,否则返回NO。此属性的默认实现返回YES。
- (nullable id)valueForKey:(NSString *)key;
给定一个键名,返回属性值或相关对象。
该方法的默认实现如下:
-
在当前类中搜索一个访问方法,方法的名称按后面的顺序匹配
-get<Key>,-<key>, 或-is<Key>。如果查询到匹配的方法就调用。- 如果返回的结果是对象指针类型则直接返回结果;
- 如果是
NSNumber支持的标量类型转换成NSNumber类型并返回; - 否则,转换完成一个
NSValue并返回。
-
如果没有查询到匹配的方法,则继续按照后面的顺序匹配:
-countOf<Key>和-indexIn<Key>OfObject:和-objectIn<Key>AtIndex:(对应NSOrderedSet定义的原始方法)和-<key>AtIndexes:(对应-[NSOrderedSet objectsAtIndexes:])。如果匹配到了count方法和indexOf方法,以及至少另外两个可能的方法中的一个,则返回一个响应所有NSOrderedSet方法的集合代理对象。每个发送到集合代理对象的NSOrderedSet消息将导致-countOf<Key>,-indexIn <Key>OfObject:,-objectIn<Key>AtIndex:,和-<Key>AtIndexes:消息被发送到-valueForkey:的原始接收者。如果接收方的类还实现了一个名称匹配模式的可选方法-get<Key>:range:该方法将在适当的时候用于最佳性能。 -
否则,继续按照后面的顺序匹配:
-countOf<Key>and-objectIn<Key>AtIndex:(对应NSArray定义的原始方法) and also-<key>AtIndexes:(对应-[NSArray objectsAtIndexes:])。如果找到一个count方法和另外两个可能的方法中的至少一个,则返回一个响应所有NSArray方法的集合代理对象。每个发送到集合代理对象的NSArray消息都将导致-countOf<Key>,-objectIn<Key>AtIndex:和-AtIndexes:消息被发送到 -valueForKey:的原始接收者。如果接收方的类还实现了一个名称匹配模式的可选方法-get<Key>:range:该方法将在适当的时候用于最佳性能。 -
否则,继续按照后面的顺序匹配:
-countOf<Key>,-enumeratorOf<Key>, and-memberOf<Key>:(对应NSSet类的原始方法)。如果找到所有这三个方法,则返回一个响应所有NSSet方法的集合代理对象。发送到集合代理对象的每个NSSet消息将导致-countOf<Key>,-enumeratorOf<Key>,和-memberOf<Key>:消息被发送到-valueForKey:的原始接收者。 -
否则,如果类中的类方法
+accessinstancevariablesdirect返回YES,则在接收方的类中搜索一个实例变量,其名称按后面顺序匹配_<key>,_is<Key>,<key>,或is<Key>。如果找到这样的实例变量,则返回接收方中实例变量的值,与步骤1中相同的转换为NSNumber或NSValue。 -
否则,调用
-valueForUndefinedKey:并返回结果。-valueForUndefinedKey:的默认实现:引发一个NSUndefinedKeyException,但你可以在你的应用程序中重写覆盖原始实现。
兼容说明:
- 为了向后二进制兼容性,在第1步和第3步之间搜索名称与模式
-_get<Key>或-_<key>匹配的访问器方法。如果找到这样的方法,则调用它,使用相同的类型转换为步骤1中的NSNumber或NSValue。但名称以下划线开头的KVC访问器方法在 Mac OS 10.3 中已被弃用。
- (void)setValue:(nullable id)value forKey:(NSString *)key;
该方法的默认实现如下:
- 在当前类中搜寻
-set<Key>:方法。如果找到了,则检查它的参数类型,如果参数类型不是对象指针类型,且值为nil,则调用-setNilValueForKey:。-setNilValueForKey:的默认实现会引发一个NSInvalidArgumentException异常,但是你可以在你的应用程序中重写它。否则,如果方法的形参类型是对象指针类型,则只需将值作为参数调用该方法。如果方法参数的类型是其他类型,则在调用方法之前执行由-valueForKey:完成的NSNumber、NSValue转换的逆操作。 - 否则,如果接收者的类的
+accessInstanceVariablesDirectly属性返回YES,则在接收者的类中按后面的顺序匹配变量名:_<key>、_is<Key>、<key>或is<Key>。如果找到这样的实例变量并且它的类型是对象指针类型,则在第一次释放实例变量的旧值之后,保留该值并将结果设置在实例变量中。 如果实例变量的类型是其他类型,则它的值是在与步骤 1 中从 NSNumber 或 NSValue 进行相同类型的转换之后设置的。 - 否则,调用
-setValue:forUndefinedKey:。-setValue:forUndefinedKey:的默认实现会引发NSUndefinedKeyException,但您可以在应用程序中覆盖它。
- (BOOL)validateValue:(inout id _Nullable * _Nonnull)ioValue forKey:(NSString *)inKey error:(out NSError **)outError;
For Collection
- (NSMutableArray *)mutableArrayValueForKey:(NSString *)key;
获取到的可变数组,添加对象将影响接收者。删除对象不影响接收者。
- (NSMutableOrderedSet *)mutableOrderedSetValueForKey:(NSString *)key;
- (NSMutableSet *)mutableSetValueForKey:(NSString *)key;
For KeyPath
- (nullable id)valueForKeyPath:(NSString *)keyPath;
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;
- (BOOL)validateValue:(inout id _Nullable * _Nonnull)ioValue forKeyPath:(NSString *)inKeyPath error:(out NSError **)outError;
- (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath;
- (NSMutableOrderedSet *)mutableOrderedSetValueForKeyPath:(NSString *)keyPath API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
- (NSMutableSet *)mutableSetValueForKeyPath:(NSString *)keyPath;
Other
可以通过运行时动态存取不存在的属性。
- (nullable id)valueForUndefinedKey:(NSString *)key;
- (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key;
当值为nil时会调用此方法,会引发一个异常。可以重写处理。
- (void)setNilValueForKey:(NSString *)key;
- (NSDictionary<NSString *, id> *)dictionaryWithValuesForKeys:(NSArray<NSString *> *)keys;
- (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *, id> *)keyedValues;
NSArray、NSOrderedSet、NSSet
集合中每个元素都会执行一次并返回集合结果
- (id)valueForKey:(NSString *)key;
集合中每个元素都会执行一次
- (void)setValue:(nullable id)value forKey:(NSString *)key;
NSDictionary、NSMutableDictionary
- (id)valueForKey:(NSString *)key; //相当于-objectForKey:
- (void)setValue:(nullable id)value forKey:(NSString *)key; //相当于-setObject:forKey:
- NSKeyValueCoding
- NSUndefinedKeyException
- NSKeyValueOperator
- NSObject(NSKeyValueCoding)
*- @property (class, readonly) BOOL accessInstanceVariablesDirectly
- - (nullable id)valueForKey:(NSString *)key;
- - (void)setValue:(nullable id)value forKey:(NSString *)key;
- - (BOOL)validateValue:(inout id _Nullable * _Nonnull)ioValue forKey:(NSString *)inKey error:(out NSError **)outError;
- For Collection
- For KeyPath
- Other
- NSArray、NSOrderedSet、NSSet
- NSDictionary、NSMutableDictionary