美文网首页
iOS:KVO浅析

iOS:KVO浅析

作者: 春暖花已开 | 来源:发表于2020-08-12 09:34 被阅读0次
#import "ViewController.h"
#import <objc/runtime.h>

///打印某个类的所有成员方法
void getAllMethodsOfClass(Class cls) {
    
    unsigned int count;
    Method *methods = class_copyMethodList(cls, &count);
    NSMutableArray *array = [NSMutableArray array];
    for (unsigned int i = 0; i < count; i++) {
        Method method = methods[i];
        [array addObject:NSStringFromSelector(method_getName(method))];
    }
    NSString *methodName = [array componentsJoinedByString:@", "];
    NSLog(@"\n方法名: \n%@", methodName);
}

@interface MZPerson : NSObject

@property (nonatomic, assign) NSInteger age;

@end

@implementation MZPerson

- (void)setAge:(NSInteger)age {
    _age = age;
}

- (void)willChangeValueForKey:(NSString *)key {
    [super willChangeValueForKey:key];
    
    NSLog(@"willChangeValueForKey:");
}

- (void)didChangeValueForKey:(NSString *)key {
    
    NSLog(@"didChangeValueForKey: --start");
    [super didChangeValueForKey:key];
    
    NSLog(@"didChangeValueForKey: --end");
}

@end


@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    MZPerson *person1 = [[MZPerson alloc] init];
    person1.age = 18;
    
    MZPerson *person2 = [[MZPerson alloc] init];
    //监听属性值的改变
    [person2 addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
    //改变值
    person2.age = 18;
    
    Class unobservedCls = object_getClass(person1);
    Class observedCls = object_getClass(person2);
    
    NSLog(@"\n没有监听类:%@\n监听之后的%@", unobservedCls, observedCls);
    NSLog(@"被监听类的父类是: %@", observedCls.superclass);
    
    //打印所有的成员方法
    getAllMethodsOfClass(observedCls);
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    
    NSLog(@"%@---%@", change[NSKeyValueChangeOldKey], change[NSKeyValueChangeNewKey]);
}

@end

输出:

willChangeValueForKey:
didChangeValueForKey: --start
0---18
didChangeValueForKey: --end

没有监听类:MZPerson
监听之后的NSKVONotifying_MZPerson

被监听类的父类是: MZPerson

方法名: 
setAge:, class, dealloc, _isKVOA

从打印可以看出:

  • 1、被监听的属性所属的类会由runtime动态生成一个类 NSKVONotifying_MZPerson,该类继承自MZPerson,并将被监听属性的 isa 指针指向新生成的类;
  • 2、新生成的类里有四个方法,分别是setAge:, class, dealloc, _isKVOA,其中前三个为重写的方法;
  • 3、被监听属性的值发生改变,是通过 _NSSetLongLongValueAndNotify() 处理并且通知调用 - observeValueForKeyPath:ofObject:change:context:

相关文章

网友评论

      本文标题:iOS:KVO浅析

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