KVO 其原理探究

简介:

什么是KVO ?

KVO这是Key-Value Observing,它提供了一种机制,指定的对象的属性被改动后,则对象就会接受到通知。
简单的说就是每次指定的被观察的对象的属性被改动后。KVO就会自己主动通知对应的观察者了。

KVO简单样例

新建一个Person类:

#import <Foundation/Foundation.h>

@interface Person : NSObject
@property (nonatomic, assign) int age;
@end

在控制器的ViewDidLoad方法里注冊KVO监听,并改变键值。

#import "ViewController.h"
#import "Person.h"

@interface ViewController ()
@property (nonatomic, strong) Person *p;
@end

@implementation ViewController

- (void)viewDidLoad {
	[super viewDidLoad];

	Person *p = [[Person alloc] init];
	p.age = 20;
        
        //注冊观察者
	[p addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];

	p.age = 30;
	self.p = p;
}

/**
 *  当监控的某个属性的值改变了就会调用
 *
 *  @param keyPath 属性名(哪个属性改了?)
 *  @param object  哪个对象的属性被改了?
 *  @param change  属性的改动情况(属性原来的值、属性最新的值)
 *  @param context void * == id
 */
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
	NSLog(@"%@对象的%@属性改变了。由旧值%@改变为新值%@", object, keyPath, change[@"old"], change[@"new"]);
}

- (void)dealloc {
	//移除KVO监听
	[self.p removeObserver:self forKeyPath:@"age"];
}

@end

打印结果为:

2015-03-17 13:38:19.635 KVOTest[2001:60b] <Person: 0x15e5cf90>对象的age属性改变了,由旧值20改变为新值30

什么是isa ?

苹果官方是这样介绍isa的:
Every object is connected to the run-time system through its isa instance variable, inherited from the NSObject class. isa identifies the object's class; it points to a structure that's compiled from the class definition. Through isa, an object can find whatever information it needs at runtime such as its place in the inheritance hierarchy, the size and structure of its instance variables, and the location of the method implementations it can perform in response to messages.

通过一个实例对象的isa。我们能够找到这个对象的全部信息,如继承架构,实例变量的size和结构,响应消息机制相应的方法入口地址。

KVO前后的isa变化

变量p在KVO监听之前的isa,是Person类,例如以下:


在注冊KVO监听之后的isa,是NSKVONotifying_Person类。例如以下:



结论

可见。在addObserver:forKeyPath:options:context:之后。对象p的isa变为了NSKVONotifying_Person。

所以,依据上面的isa介绍,响应setAge的方法,实际上是对象p的isa即NSKVONotifying_Person类的setAge方法,并非原Person类的setAge方法。

能够大胆想象,NSKVONotifying_Person类是Person类的子类,在NSKVONotifying_Person类内部,重写了setAge方法。而且在setAge方法里让监听器调用了observeValueForKeyPath:ofObject:change:context:方法。

那么,NSKVONotifying_Person是怎么产生的呢?简单的说,是由runtime产生的。

兴许文章将介绍objective-c的runtime机制。


个人原创,欢迎转载,转载请注明出处:http://blog.csdn.net/iosHot

版权声明:本文博客原创文章。博客,未经同意,不得转载。







本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/4722184.html,如需转载请自行联系原作者


相关文章
|
7月前
|
Java
Java多态:如何实现“一箭双雕”的编程艺术?
【6月更文挑战第17天】Java中的多态是编程灵活性的关键,它允许通用接口处理不同类型的对象。通过抽象基类或接口,子类可以实现各自的行为。例如,在动物音乐会场景中,一个`Animal`接口让狮子、猴子和企鹅都能唱歌,调用`sing()`即自动匹配相应行为。同样,在图形绘制示例中,`Shape`基类让绘制圆形、正方形和三角形变得简单,只需调用`draw()`。多态减少了代码冗余,增强了可扩展性和可维护性,是解决需求变化的利器。
40 0
|
8月前
|
C++
【C++】一文深入浅出带你参透库中的几种 [ 智能指针 ]及其背后实现原理(代码&图示)
【C++】一文深入浅出带你参透库中的几种 [ 智能指针 ]及其背后实现原理(代码&图示)
|
Kubernetes 监控 Linux
【k8s 系列】k8s 学习二十七 - 5,k8s 自身原理 5
我们知道容器是通过 pod 来承载的,我们在 k8s 中,服务都是跑在 pod 里面的,pod 里面可以跑 1 个容器,或者跑多个容器,那么咱们 pod 里面跑 1 个服务容器,咱真的就以为里面就只有这样个容器吗
109 0
|
Kubernetes API 调度
【k8s 系列】k8s 学习二十七-2,k8s 自身原理 2
前面我们说到 K8S 的基本原理和涉及的四大组件,分享了前两个组件 etcd 和 ApiServer 这一次我们接着分享一波
126 0
|
存储 Kubernetes API
【k8s 系列】k8s 学习二十七-1,k8s 自身原理 1
咱们从 pod 一直分享到最近的 Statefulset 资源,到现在好像我们只是知道如何使用 k8s,如何按照 k8s 设计好的规则去应用,去玩 k8s
165 0
|
Kubernetes 监控 API
【k8s 系列】k8s 学习二十七-3,k8s 自身原理 3
前面有分享到 master 主节点上的 四个组件,etcd,ApiServer,scheduler,controller manager
107 0
|
存储 Kubernetes 监控
【k8s 系列】k8s 学习二十七 - 4,k8s 自身原理 4
前面咱们分享了 mater 和 worker 节点里面都有哪些组件,他们又是各自主要负责的工作是什么,现在我们心里应该都有数了吧
154 0
|
网络协议 测试技术 Go
反射的引出和应用场景|学习笔记
快速学习反射的引出和应用场景
|
C++ iOS开发 Windows
手把手带你去分析NSObject本质是什么
这篇行文主要讲 NSObject 对象三连问:NSObject本质是什么,占用多少内存,以及怎么去分析。 从下图我们可以看到,我们平时编写的 Objective-C 代码,最终转换到机器语言的过程: https://img-blog.csdnimg.cn/2a6a930a8d3546f896d7527a95c3a576.png 换句话说,Objective-C的面向对象都是基于C\C++的数据结构实现的,或者说其底层实现其实都是C\C++代码。
189 0
手把手带你去分析NSObject本质是什么
|
架构师 Java 编译器
抽丝剥茧聊协程之深入理解Continuation原理
抽丝剥茧聊协程之深入理解Continuation原理
抽丝剥茧聊协程之深入理解Continuation原理