KVO

作者: 梓华 | 来源:发表于2018-09-03 17:48 被阅读6次

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

    相关文章

      网友评论

          本文标题:KVO

          本文链接:https://www.haomeiwen.com/subject/fdzbwftx.html