参考
https://www.jianshu.com/p/4748ef75126a
https://blog.csdn.net/wzzvictory/article/details/9674431?utm_source=tuicool
@interface Person : NSObject
@property (nonatomic, assign) int age;
@end
_person = [[Person alloc] init];
/**
* 添加观察者
*
* @param observer 观察者
* @param keyPath 被观察的属性名称
* @param options 观察属性的新值、旧值等的一些配置(枚举值,可以根据需要设置,例如这里可以使用两项)
* @param context 上下文,可以为nil。
*/
[_person addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
/**
* KVO回调方法
*
* @param keyPath 被修改的属性
* @param object 被修改的属性所属对象
* @param change 属性改变情况(新旧值)
* @param context context传过来的值
*/
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
NSLog(@"%@对象的%@属性改变了:%@", object, keyPath, change);
//当有多个被观察者的时候就要写判断
if([keyPath isEqualToString:@"age"] && object == _person)
{
NSLog(@"\noldnum:%@ newnum:%@", [change valueForKey:@"old"], [change valueForKey:@"new"]);
}
}
/**
* 移除观察者
*/
- (void)dealloc
{
[_person removeObserver:self forKeyPath:@"age"];
}
其他
@interface Person : NSObject
{
@public
int _age;
}
@property (nonatomic, assign) int age;
@end
@implementation Person
- (void)setAge:(int)age
{
_age = age;
NSLog(@"%s",__func__);
}
@end
static int i = 1;
//setter方法赋值
//_person.age = i++;
//KVC赋值
//[_person setValue:@(i++) forKey:@"age"];
//成员变量赋值 不会调用监听
_person->_age = i++;
NSLog(@"%d", _person->_age);
其他
最后的调用栈- (void)setName:(NSString *)name
{
_name = [name copy];
NSLog(@"%s", __FUNCTION__);
}
- (void)willChangeValueForKey:(NSString *)key
{
[super willChangeValueForKey:key];
NSLog(@"%s", __FUNCTION__);
NSLog(@"self->isa:%@", object_getClass(self));
NSLog(@"self class:%@", [self class]);
}
- (void)didChangeValueForKey:(NSString *)key
{
[super didChangeValueForKey:key];
NSLog(@"%s", __FUNCTION__);
NSLog(@"self->isa:%@", object_getClass(self));
NSLog(@"self class:%@", [self class]);
}
2018-09-03 17:38:34.600836+0800 KVO[359:124313] -[Person willChangeValueForKey:]
2018-09-03 17:38:42.592813+0800 KVO[359:124313] self->isa:NSKVONotifying_Person
2018-09-03 17:38:43.336736+0800 KVO[359:124313] self class:Person
2018-09-03 17:40:28.206718+0800 KVO[359:124313] -[Person didChangeValueForKey:]
2018-09-03 17:40:28.206908+0800 KVO[359:124313] self->isa:NSKVONotifying_Person
2018-09-03 17:40:28.207017+0800 KVO[359:124313] self class:Person
NSKVONotifying_Person 是子类
NSKVONotifying_Person
- (void)setName:(NSString *)newName
{
[self willChangeValueForKey:@"name"]; // KVO在调用存取方法之前总调用
[super setValue:newName forKey:@"name"]; // 调用父类的存取方法
[self didChangeValueForKey:@"name"]; // KVO在调用存取方法之后总调用
}
include <objc/runtime.h>
self->isa
object_getClass
target build setting direct usage of 'isa' set NO
网友评论