美文网首页
聊一聊KVO

聊一聊KVO

作者: 晨阳Xia | 来源:发表于2020-12-23 12:22 被阅读0次

    kvo具体的实现过程

    1.首先只能作用于属性
    2.要注册观察者

    注册观察者之后,instance对象有什么变化?

        @interface Student : NSObject{
            double _no;
            double _no1;
            double _no2;
        }
        
        @property(nonatomic, strong) NSString *name;
        
        @end
        
        @implementation Student
        
        @end
        // NSKVONotifying_Student
        self.studentObj1 = [[Student alloc] init];
            NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
            [self.studentObj1 addObserver:self forKeyPath:@"name" options:options context:nil];
        
        // Student    
        self.studentObj2 = [[Student alloc] init];
    

    同一类型的两个instance对象没有注册观察则,isa指向Student类对象
    同一类型的两个instance对象,注册了观察者之后,isa指向NSKVONotifying_Student类对象。底层是runtime动态创建了NSKVONotifying_Student类型的新类,这个类是Student的子类。

        // 系统重写监听类的伪代码
        @interface NSKVONotifying_Student : Student
        
        @end
        
        @implementation NSKVONotifying_Student
        // 重写了setName:方法
        - (void)setName:(NSString *)name {
            _NSSetIntValueAndNofify();
        }
        
        void _NSSetIntValueAndNofify() {
            [self willChangeValueForKey:@"name"];
            [super setName:@"name"];
            [self didChangeValueForKey:@"name"];
        }
        
        - (void)didChangeValueForKey:(NSString *)key {
            [observe observeValueForKeyPath:key ofObject:self change:change context:change];
        }
        
        @end
    

    NSKVONotifying_Student

    它的instance对象的isa指向它自己的class对象,他的class对象的isa指向meta-class对象。

    代理和kvo的效率哪个更高

    代理的效率高,kvo需要runtime动态生成类

    kvo应用场景

    MJRefresh

    如何查看runtime重新生成的kvo新类是重写了哪些方法?

    - (void)viewDidLoad {
        [super viewDidLoad];
        self.studentObj1 = [[Student alloc] init];
            self.studentObj2 = [[Student alloc] init];
            
            NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
            [self.studentObj1 addObserver:self forKeyPath:@"name" options:options context:nil];
            
            [self printMethodNameWithClass:object_getClass(self.studentObj1)];
            
            [self printMethodNameWithClass:object_getClass(self.studentObj2)];
    }
        
    // 打印类中的方法  
    - (void)printMethodNameWithClass:(Class)class {
        NSMutableString *methodNames = [NSMutableString string];
        unsigned int count;
        Method *methodList = class_copyMethodList(class, &count);
        for (int i = 0; i < count; i++) {
            Method method = methodList[i];
            NSString *methodName = NSStringFromSelector(method_getName(method));
            [methodNames appendFormat:@"%@ ",methodName];
        }
        free(methodList);
        NSLog(@"className%s - allMethodName%@",class_getName(class),methodNames);
    }
    
    // 打印结果
    2020-12-23 12:09:31.447274+0800 FiftyTwo[12958:724869] classNameNSKVONotifying_Student - allMethodNamesetName: class dealloc _isKVOA
    2020-12-23 12:09:31.447466+0800 FiftyTwo[12958:724869] classNameStudent - allMethodName.cxx_destruct name setName:
    

    响应式编程和kvo的区别

    kvo的本质描述

    利用runtime,动态生成一个子类NSKVONotifying_Class,并让instance实例指向这个子类,当修改instance对象的属性时,会调用Foundation的NSSetIntValueAndNotify函数,
    NSSetIntValueAndNotify函数代码如下

    - (void)setName:(NSString *)name {
            _NSSetIntValueAndNofify();
        }
        
        void _NSSetIntValueAndNofify() {
            [self willChangeValueForKey:@"name"];
            [super setName:@"name"];
            [self didChangeValueForKey:@"name"];
        }
        
        - (void)didChangeValueForKey:(NSString *)key {
            [observe observeValueForKeyPath:key ofObject:self change:change context:change];
        }
    
    

    如何手动出发kvo

    如此便可触发kvo
    [self.studentObj1 willChangeValueForKey:@"name"];
    [self.studentObj1 didChangeValueForKey:@"name"];

    相关文章

      网友评论

          本文标题:聊一聊KVO

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