[iOS] KVC 和 KVO

开发iOS经常会看见KVO和KVC这两个概念,特地了解了一下。

我的新博客wossoneri.com link

KVC Key Value Coding

KVC是一种用间接方式访问类的属性的机制。比如你要给一个类中的属性赋值或者取值,可以直接通过类和点运算符实现,当然也可以使用KVC。不过对于私有属性,点运算符就不起作用,因为私有属性不暴露给调用者,不过使用KVC却依然可以实现对私有属性的读写。

先看一下KVC的一部分源码,当然只能看到头文件:

// NSKeyValueCoding.h

@interface NSObject(NSKeyValueCoding)

+ (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; - (NSMutableArray *)mutableArrayValueForKey:(NSString *)key; - (NSMutableOrderedSet *)mutableOrderedSetValueForKey:(NSString *)key NS_AVAILABLE(10_7, 5_0); - (NSMutableSet *)mutableSetValueForKey:(NSString *)key; - (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 NS_AVAILABLE(10_7, 5_0);
- (NSMutableSet *)mutableSetValueForKeyPath:(NSString *)keyPath; - (nullable id)valueForUndefinedKey:(NSString *)key;
- (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key;
- (void)setNilValueForKey:(NSString *)key;
- (NSDictionary<NSString *, id> *)dictionaryWithValuesForKeys:(NSArray<NSString *> *)keys;
- (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *, id> *)keyedValues; @end @interface NSArray<ObjectType>(NSKeyValueCoding) - (id)valueForKey:(NSString *)key;
- (void)setValue:(nullable id)value forKey:(NSString *)key; @end @interface NSDictionary<KeyType, ObjectType>(NSKeyValueCoding) - (nullable ObjectType)valueForKey:(NSString *)key; @end @interface NSMutableDictionary<KeyType, ObjectType>(NSKeyValueCoding) - (void)setValue:(nullable ObjectType)value forKey:(NSString *)key; @end @interface NSOrderedSet<ObjectType>(NSKeyValueCoding) - (id)valueForKey:(NSString *)key NS_AVAILABLE(10_7, 5_0);
- (void)setValue:(nullable id)value forKey:(NSString *)key NS_AVAILABLE(10_7, 5_0); @end @interface NSSet<ObjectType>(NSKeyValueCoding) - (id)valueForKey:(NSString *)key;
- (void)setValue:(nullable id)value forKey:(NSString *)key; @end

可以看到这个类里面包含了对类NSObject,NSArray,NSDictionary,NSMutableDictionary,NSOrderedSet,NSSet的拓展。拓展的方法基本上为

- (id)valueForKey:(NSString *)key;
- (void)setValue:(nullable id)value forKey:(NSString *)key;

也就是说,基本上Objective-C里所有的对象都支持KVC操作,操作包含如上两类方法,动态读取和动态设值。

好多地方说是NSObject实现了NSKeyValueCoding协议。而代码里是类的拓展。这两种说法是相通的嘛?

举个

上一篇:Java 学习笔记(11)——lambda 表达式


下一篇:高放的c++学习笔记之lambda表达式