1.生成子类
系统会通过runtime动态生成一个名为NSKVONotifying_xxx(被监听类名)继承自被监听类的子类
例如 YHObject -> NSKVONotifying_YHObject
调用方法 objc_allocateClassPair([YHObject class], "YHObject", 0);
@interface YHObject : NSObject
@property (nonatomic, assign) int age;
@end
@implementation YHObject
@end
@interface NSKVONotifying_YHObject : YHObject
@end
@implementation NSKVONotifying_YHObject
- (void)setAge:(int)age
{
_NSSetIntValueAndNotify();
}
// 伪代码
void _NSSetIntValueAndNotify()
{
[self willChangeValueForKey:@"age"];
[super setAge:age];
[self didChangeValueForKey:@"age"];
}
- (void)didChangeValueForKey:(NSString *)key
{
// 通知监听器,某某属性值发生了改变
[oberser observeValueForKeyPath:key ofObject:self change:nil context:nil];
}
// 屏幕内部实现,隐藏了NSKVONotifying_MJPerson类的存在
- (Class)class
{
return [YHObject class];
}
- (void)dealloc
{
// 收尾工作
}
- (BOOL)_isKVOA
{
return YES;
}
@end
2.重写父类的set方法
子类重写被监听属性的set方法,在set方法里面调用 _NSSetIntValueAndNotify();
_NSSetIntValueAndNotify的大概实现是这样的
[self willChangeValueForKey:@"age"]; // 将会改变
[super setAge:age]; // 调用父类的set方法给成员变量赋值
[self didChangeValueForKey:@"age"]; // 改变
didChangeValueForKey
通知监听器某某属性发生了改变既调用公共的方法
[oberser observeValueForKeyPath:key ofObject:self change:nil context:nil];
3子类重写class方法
// 返回原来的类来迷惑开发者,隐藏实现原理
- (Class)class
{
return [YHObject class];
}
网友评论