【iOS】浅谈KVO实现原理

2017-01-14  本文已影响36人  Always_on

最近研究一下KVO的实现原理,写篇博文记录下;

用以下例子做说明:

创建两个类CYPerson和CYPhone,CYPhone中属性​electricity;

​当phone对象的属性​electricity改变时,person进行处理操作,代码如下

#import <Foundation/Foundation.h>

@interface CYPhone : NSObject

@property(nonatomic,assign)NSInteger electricity;

@end

CYPerson需实现:- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

#import "CYPerson.h"

@implementation CYPerson

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    NSLog(@"object:%@,keyPath:%@,change:%@",object,keyPath,change);
}
@end
#import "ViewController.h"
#import "CYPerson.h"
#import "CYPhone.h"

@interface ViewController ()
@property (nonatomic ,strong) UITextField *textF;
@property (nonatomic ,strong) CYPerson *person;
@property (nonatomic ,strong) CYPhone *phone;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // Do any additional setup after loading the view, typically from a nib.
    self.view.backgroundColor = [UIColor grayColor];
    _person = [CYPerson new];
    _phone = [CYPhone new];
    [_phone addObserver:self.person forKeyPath:@"electricity" options:NSKeyValueObservingOptionNew context:nil];
    
    UITextField *textField = [[UITextField alloc]initWithFrame:CGRectMake(20, 100, [UIScreen mainScreen].bounds.size.width - 40, 40)];
    textField.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:textField];
    _textF = textField;
    
    UIButton *changeBtn = [[UIButton alloc]initWithFrame:CGRectMake(20, 175, [UIScreen mainScreen].bounds.size.width - 40, 40)];
    [changeBtn  setTitle:@"确认电量" forState:UIControlStateNormal];
    [changeBtn addTarget:self action:@selector(changeBtnClick) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:changeBtn];
}
- (void)changeBtnClick
{
    self.phone.electricity = [self.textF.text integerValue];
    
}
Snip20170105_9.png

输入数字,点击确认后对phone的electricity值进行改变,我们添加断点调试,控制台结果如下


001.png

isa,简单点说其指向的就是真实类型;

phone对象的类为CYPhone,isa指向的是NSKVONotifying_CYPhone,说明当我们在使用KVO的时候,runtime过程中会动态的创建一个类NSKVONotifying_对象类名,进而实现观察。

​如有问题请大家提出,多多指教,共同进步。

上一篇下一篇

猜你喜欢

热点阅读