Runtime系列導讀
簡介
KVC是Key Value Coding的縮寫,意思是鍵值編碼。 在iOS中,提供了一種方法通過使用屬性的名稱(也就是Key)來間接訪問對象屬性的方法,這個方法可以不通過getter/setter方法來訪問對象的屬性。 用KVC可以間接訪問對象屬性的機制。通常我們使用valueForKey 來替代getter 方法,setValue:forKey來代替setter方法。
用法
-
常見API
- - (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
- - (void)setValue:(id)value forKey:(NSString *)key;
- - (id)valueForKeyPath:(NSString *)keyPath;
- - (id)valueForKey:(NSString *)key;
調用方式
-(void)testKVO2
{
self.test = [KVOTest new];
[self.test setValue:@(10) forKey:@"age"];
NSKeyValueObservingOptions option = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
[self.test addObserver:self forKeyPath:@"age" options:option context:nil];
[self.test setValue:@(20) forKey:@"age"];
NSLog(@"%ld", [[self.test valueForKey:@"age"] integerValue]);
}
- 打印日志
2022-06-25 22:25:06.887730+0800 StudyApp[31993:1358988] age - {
kind = 1;
new = 20;
old = 10;
}
2022-06-25 22:25:06.887791+0800 StudyApp[31993:1358988] didChangeValueForKey:age,0x600001ce8470
2022-06-25 22:25:06.887835+0800 StudyApp[31993:1358988] 20
實現原理
網上對于這塊的講解比較多,我就不重復描述了,轉載兩個比較好描述該原理的流程圖。
- setValue:forKey:的原理
image.png
- valueForKey:的原理
image.png
答疑
給不存在的屬性賦值,會怎么樣?
- 會crash
[self.test setValue:@(10) forKey:@"age1"]; // 產生以下crash
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<KVOTest 0x600002ed45f0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key age1.'
給不存在的屬性取值,會怎么樣?
- 會crash
[self.test valueForKey:@"age1"] // 產生以下Crash
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<KVOTest 0x6000033dc620> valueForUndefinedKey:]: this class is not key value coding-compliant for the key age1.'