iOS用什么方式实现对一个对象的KVO
- 利用Runtime API的动态特性 动态生成一个子类 并且让instance的isa指针指向这个全新的子类
- 当修改instance对象的属性时 会调用Foundation的_NSSet*ValueAndNotify的函数
a.调用willChangeValueForKey:
b.父类原先的setter
c.调用didChangeValueForKey:
内部会调用observer的observeValueForKeyPath:ofObject:change:context:方法
如何手动触发KVO
手动调用willChangeValueForKey:和didChangeValueForKey:
直接修改成员变量会触发KVO么?
不会触发KVO
KVO
KVO的全称是Key-Value Observing 俗称"键值监听" 可以用于监听某个对象属性值的改变
[self.person methodForSelector:@selector(selector)] 获取方法的具体实现
_NSSet*ValueAndNotify的内部实现
1.调用willChangeValueForKey:
2.调用原来的setter实现
3.调用didChangeValueForKey:
didChangeValueForKey:内部会调用observer的observeValueForKeyPath:ofObject:change:context:方法
使用了KVO 会重写-(Class )class 和 -(void)dealloc 和 -(BOOL)_isKVOA方法
NSKVONotifying_MJPerson 里面重写class方法 是为了隐藏真正的类对象NSKVONotifying_MJPerson 如果不重写class方法 那么就会往他的superclass里面寻找方法 直到在NSObject里面寻找到class方法 调用class方法 会返回真正的类对象名称
获取类对象里面的对象方法
unsigned int count;
//获得方法数组
Method *methods = class_copyMethodList(object_getClass(self.person), &count);
//存储方法名
NSMutableString *methodNames = [NSMutableString string];
//遍历所有的方法
for (int i = 0; i < count; i++) {
//获得方法
Method method = methods[i];
//获得方法名
NSString *methodName = NSStringFromSelector(method_getName(method));
//拼接方法名
[methodNames appendString:methodName];
[methodNames appendString:@", "];
}
//释放
free(methods);
//打印方法名
NSLog(@"%@ %@",self.person1,methodNames);
网友评论