KVO

参考
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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 作者:wangzz原文地址:http://blog.csdn.net/wzzvictory/article/det...
    反调唱唱阅读 4,753评论 0 5
  • 前言: 本文基本不讲KVC/KVO的用法,只结合网上的资料说说对这种技术的理解。 由于KVO内容较少,而且是以KV...
    土b兰博王阅读 8,212评论 0 33
  • 一. KVO是键值观察,是Objective-C对观察者模式的实现,每次当被观察者对象的某个属性值发生改变时,注册...
    魂一飞阅读 2,187评论 0 0
  • 鬓如霜雪寒风里,步履维艰相聚少。 回首不舍泪纷纷,扬扬洒洒天地间。 好儿郎仗剑天涯,是非斩尽苍生苦。 长河苦相思更...
    夜景黑色调阅读 1,131评论 0 2
  • 茶是岁月最好的记录者 煮沸一壶水,触摸岁月的痕迹 同一泡陈年老茶交谈 就是将那段没有你的日子 一杯一盏的 慢慢的 ...
    任焕红阅读 1,690评论 0 0