zoukankan      html  css  js  c++  java
  • 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

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

  • 相关阅读:
    开源图标字体 uiw-iconfont v1.2.6 发布,新增图标
    OAuth授权登录
    网站视觉设计规范
    LOGO有哪几种常规设计思路?
    Web设计规范----控件、组件
    前端工程师的新选择WebApp
    openstack学习-网络管理 (转)
    理解OpenStack与SDN控制器的集成(转)
    NFV MANO 架构
    Raid 磁盘阵列
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4722184.html
Copyright © 2011-2022 走看看