iOS的kvo的实现原理

kvo实现原理

自动创建一个原来类的子类,如NSKVONotifying_XX,将原来类的isa指针指向新建的类,重写setter方法,通过willChangeValueForKey,didChangeValueForKey来检测属性值的变化。

removeObserver就是将isa指针指向原来的类

举个栗子:

//XYPerson.h
#import 

@interface XYPerson : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSUInteger age;
- (void)printInfo;

@end

//XYPerson.m
#import "XYPerson.h"
#import 

@implementation XYPerson
- (void)printInfo{
    NSLog(@"isa:%@, supper class:%@", NSStringFromClass(object_getClass(self)), class_getSuperclass(object_getClass(self)));
    NSLog(@"self:%@, [self superclass]:%@", self, [self superclass]);
    NSLog(@"age setter function pointer:%p", class_getMethodImplementation(object_getClass(self), @selector(setAge:)));
    NSLog(@"name setter function pointer:%p", class_getMethodImplementation(object_getClass(self), @selector(setName:)));
    NSLog(@"printInfo function pointer:%p", class_getMethodImplementation(object_getClass(self), @selector(printInfo)));
}
@end

//MainController.m
- (void)viewDidLoad {
    [super viewDidLoad];
    
    XYPerson *person = [XYPerson new];
    person.name = @"Will";
    person.age = 30;
    self.person = person;
    [self.person printInfo];
    [self.person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
    NSLog(@"------------");
    [self.person printInfo];

    [self.person removeObserver:self forKeyPath:@"name"];
    NSLog(@"------------");
    [self.person printInfo];
}

打印如下

2018-03-06 15:22:46.631080+0800 tableView[50139:1031782] isa:XYPerson, supper class:NSObject
2018-03-06 15:22:46.631372+0800 tableView[50139:1031782] self:, [self superclass]:NSObject
2018-03-06 15:22:46.631485+0800 tableView[50139:1031782] age setter function pointer:0x101e876a0
2018-03-06 15:22:46.631692+0800 tableView[50139:1031782] name setter function pointer:0x101e87640
2018-03-06 15:22:46.631800+0800 tableView[50139:1031782] printInfo function pointer:0x101e873a0
2018-03-06 15:22:46.632256+0800 tableView[50139:1031782] ------------
2018-03-06 15:22:46.632437+0800 tableView[50139:1031782] isa:NSKVONotifying_XYPerson, supper class:XYPerson
2018-03-06 15:22:46.632654+0800 tableView[50139:1031782] self:, [self superclass]:NSObject
2018-03-06 15:22:46.632782+0800 tableView[50139:1031782] age setter function pointer:0x101e876a0
2018-03-06 15:22:46.632888+0800 tableView[50139:1031782] name setter function pointer:0x104ab6efe
2018-03-06 15:22:46.632979+0800 tableView[50139:1031782] printInfo function pointer:0x101e873a0
2018-03-06 15:22:46.633102+0800 tableView[50139:1031782] ------------
2018-03-06 15:22:46.634074+0800 tableView[50139:1031782] isa:XYPerson, supper class:NSObject
2018-03-06 15:22:46.634357+0800 tableView[50139:1031782] self:, [self superclass]:NSObject
2018-03-06 15:22:46.634536+0800 tableView[50139:1031782] age setter function pointer:0x101e876a0
2018-03-06 15:22:46.634644+0800 tableView[50139:1031782] name setter function pointer:0x101e87640
2018-03-06 15:22:46.634779+0800 tableView[50139:1031782] printInfo function pointer:0x101e873a0

addObserver新建了一个继承于XYPersonNSKVONotifying_XYPerson

你可能感兴趣的:(iOS的kvo的实现原理)