kvo实现原理_KVC、KVO实现原理

一、KVC运用了一个isa-swizzling技术。isa-swizzling就是类型混合指针机制。KVC主要通过isa-swizzling,来实现其内部查找定位的。isa指针,如其名称所指,(就是is a kind of的意思),指向维护分发表的对象的类。该分发表实际上包含了指向实现类中的方法的指针,和其它数据。

比如说如下的一行KVC的代码:

[site setValue:@"sitename" forKey:@"name"];

就会被编译器处理成:

SEL sel = sel_get_uid ("setValue:forKey:");

IMP method = objc_msg_lookup (site->isa,sel);

method(site, sel, @"sitename", @"name");

首先介绍两个基本概念:

(1)SEL数据类型:它是编译器运行Objective-C里的方法的环境参数。

(2)IMP数据类型:他其实就是一个编译器内部实现时候的函数指针。当Objective-C编译器去处理实现一个方法的时候,就会指向一个IMP对象,这个对象是C语言表述的类型。

KVC再某种程度上提供了访问器的替代方案。不过访问器方法是一个很好的东西,以至于只要是有可能,KVC也尽量再访问器方法的帮助下工作。为了设置或者返回对象属性,KVC按顺序使用如下技术:

1)检查是否存在名为-set:的方法,并使用它做设置值。对于-get和-set:方法,将大写Key字符串的第一个字母,并与Cocoa的方法命名保持一致;

2)如果上述方法不可用,则检查名为-_、-_is(只针对布尔值有效)、-_get和-_set:方法;

3)如果没有找到访问器方法,可以尝试直接访问实例变量。实例变量可以是名为:或_;

4)如果仍为找到,则调用valueForUndefinedKey:和setValue:forUndefinedKey:方法。这些方法的默认实现都是抛出异常,我们可以根据需要重写它们。

二、KVO是基于KVC实现的,看下面的代码:

#pragma mark - KVO实现原理

Person *person = [[Person alloc] init];

[person setName:@"Jacedy"];

// 设置监听

[person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];

[person setName:@"Jack"];

self.person = person;

}

// 响应监听

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{

NSLog(@"%@ 对象的 %@ 属性改变了:%@", object, keyPath, change);

}

- (void)dealloc

{

// 移除监听

[self.person removeObserver:self forKeyPath:@"name"];

}

对代码进行断点跟踪发现如下:

当添加了监听后:

不难发现,person对象的isa指针由Person变成了NSKVONotifying_Perosn。其实,当某个类的对象第一次被观察时,系统就会在运行期动态地创建该类的一个派生类,在这个派生类中重写基类中任何被观察属性的 setter 方法。派生类在被重写的 setter 方法实现真正的通知机制:

- (void)setName:(NSString *)name

{

[super setName:name];

[监听器 observeValueForKeyPath:@"name"  ofObject:self  change:@{}  context:nil];

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值