最近研究一下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];
}
输入数字,点击确认后对phone的electricity值进行改变,我们添加断点调试,控制台结果如下
isa,简单点说其指向的就是真实类型;
phone对象的类为CYPhone,isa指向的是NSKVONotifying_CYPhone,说明当我们在使用KVO的时候,runtime过程中会动态的创建一个类NSKVONotifying_对象类名,进而实现观察。
如有问题请大家提出,多多指教,共同进步。