KVO内部实现原理
KVO的原理:
只要给一个对象注册一个监听, 那么在运行时, 系统就会自动给该对象生成一个子类对象, (格式如:NSKVONotifying_className),
并且重写自动生成的子类对象的被监听属性的set方法, 然后在set方法中通知监听者
// // ViewController.m // KVO内部实现原理 // // Created by sw on 15/4/13. // Copyright © 2015年 sw. All rights reserved. // #import "ViewController.h" #import "Person.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // KVO == Key Value Observing // 作用: 可以监听某个对象属性的改变 Person *p = [Person new]; p.name = @"ws"; p.age = 30; /* 第一个参数: 告诉系统哪个对象监听 第二个参数: 监听当前对象的哪个属性 第三个参数: 监听到属性改变之后, 传递什么值 第四个参数: 需要传递的参数 (这个参数不是传递给属性的) */ // 给p这个对象添加一个监听 , 监听p对象的age属性的改变, 只要age属性改变就通知self [p addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil]; p.age = 50; NSLog(@"-------------------"); // p.age = 100; // 注意: 如果使用KVO监听某个对象的属性, 当对象释放之前一定要移除监听 // reason: 'An instance 0x7f9483516610 of class Person was deallocated while key value observers were still registered with it. // 注意: KVO只能监听通过set方法修改的值 /* KVO的原理: 只要给一个对象注册一个监听, 那么在运行时, 系统就会自动给该对象生成一个子类对象, 并且重写自动生成的子类对象的被监听属性的set方法, 然后在set方法中通知监听者 NSKVONotifying_Person */ p->_age = 998; // 从p对象上移除self对它的age属性的监听 [p removeObserver:self forKeyPath:@"age"]; } // 只要监听到属性的改变就会调用 // keyPath: 被监听的属性名称 // object : 被监听的对象 // context: 注册监听的时候传入的值 - (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary *)change context:(nullable void *)context { NSLog(@"keyPath = %@, object = %@ , change = %@, context = %@", keyPath, object, change, context); } @end