Knowledge is virtue while ignorance is evil. 知识即美德,无知即罪恶。
---- 苏格拉底
3-1.KVC.png
一图胜千言
一 setValue:forKey:赋值原理
3-2KVC赋值原理.png
二 valueForkey:取值原理
3-3 kvc取值原理.png
三 :KVC修改属性是否会触发KVO?为什么?
创建一个命令行工程
//Person
@interface Person : NSObject
@property (nonatomic, assign) int age;
@end
#pragma mark - 为什么通过KVC进行赋值 会触发 KVO监听。
/**
使用KVC 会触发下面两个方法。(手动触发KVO也是通过触发下面两个方法)
- (void)willChangeValueForKey:(NSString *)key
- (void)didChangeValueForKey:(NSString *)key
didChangeValueForKey 方法内部会调用监听器的方法。 属性值发生变化--->触发KVO
*/
- (void)willChangeValueForKey:(NSString *)key {
[super willChangeValueForKey:key];
NSLog(@"willChangeValueForKey ");
}
- (void)didChangeValueForKey:(NSString *)key {
NSLog(@"didChangeValueForKey - begin");
[super didChangeValueForKey:key];
NSLog(@"didChangeValueForKey - end");
}
//监听者 RBObserver
@interface RBObserver : NSObject
@end
@implementation RBObserver
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
NSLog(@"%@对象的%@属性发生的变化%@",object,keyPath,change);
}
@end
//main.m
#import "Person.h"
#import "RBObserver.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *person = [[Person alloc] init];
//添加KVO监听
RBObserver *observer = [[RBObserver alloc] init];
NSKeyValueObservingOptions options = NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew;
[person addObserver:observer forKeyPath:@"age" options:options context:nil];
//KVC赋值:是否会触发监听方法。
[person setValue:@10 forKey:@"age"];
NSLog(@"%d",person.age);
//移除KVO监听
[person removeObserver:observer forKeyPath:@"age"];
}
return 0;
}
也就说kvc内部会调用KVO的 willChangeValueForKey:和 didChangeValueForKey:方法(这个方法内部会调用监听者的监听方法。)
手动触发KVO也是通过这两个方法实现的。
这两个方法是NSObject(NSKeyValueObserverNotification) 分类里面的方法。
3-4KVO的willchangge 和didchange方法.png
本文代码可在github.com上查看。
LowLayerTheoryNote










网友评论