zoukankan      html  css  js  c++  java
  • KVC&KVO&NSNotification

    KVC,即是指 NSKeyValueCoding,一个非正式的 Protocol,提供一种机制来间接访问对象的属性。KVO 就是基于 KVC 实现的关键技术之一。

    一个对象拥有某些属性。比如说,一个 Person 对象有一个 name 和一个 age 属性。以 KVC 说法,Person 对象分别有一个 value 对应他的 name 和 address 的 key。 key 只是一个字符串,它对应的值可以是任意类型的对象。从最基础的层次上看,KVC 有两个方法:一个是设置 key 的值,另一个是获取 key 的值。如下面的例子:

    #import "ViewController.h"
    #import "Person.h"
    @interface ViewController ()
    @property(nonatomic,strong)Person* p;
    @end
    @implementation ViewController
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        self.p=[[Person alloc]init];
        self.p.father=[[Person alloc]init];
        
        //KVC 演示
        [self.p setValue:@"mrzhang" forKey:@"name"];
        [self.p setValue:@"laozhang" forKeyPath:@"father.name"];
        
        NSString* name=[self.p valueForKey:@"name"];
    
        
        NSLog(@"person:name:%@ father name:%@",name,self.p.father.name);
    }

    使用plist 来加载,直接可以对 对象里的实例进行赋值或读取

    Person.h

    person.plist 文件如下图

       NSString* path=[[NSBundle mainBundle] pathForResource:@"person" ofType:@"plist"];
        
        NSArray * arr=[NSArray arrayWithContentsOfFile:path];
        
       //可以直接取father 属性 不需要我们先实例出Father对象
        NSLog(@">>>%@", [arr valueForKeyPath:@"father.name"]);

    K-V 的形式取值或赋值减小了耦合度key 与 key path 要区分开来,key 可以从一个对象中获取值,而 key path 可以将多个 key 用点号 “.” 分割连接起来

     KVO:

            当指定的对象的属性被修改了,允许对象接受到通知的机制。每次指定的被观察对象的属性被修改的时候,KVO都会自动的去通知相应的观察者

     KVO的优点:
    当 有属性改变,KVO会提供自动的消息通知。这样的架构有很多好处。首先,开发人员不需要自己去实现这样的方案:每次属性改变了就发送消息通知。这是KVO 机制提供的最大的优点。因为这个方案已经被明确定义,获得框架级支持,可以方便地采用。开发人员不需要添加任何代码,不需要设计自己的观察者模型,直接可 以在工程里使用。其次,KVO的架构非常的强大,可以很容易的支持多个观察者观察同一个属性,以及相关的值。
    KVO如何工作:
    需要三个步骤来建立一个属性的观察员。理解这三个步骤就可以知道KVO如何设计工作的。

    (1)首先,构思一下如下实现KVO是否有必要。比如,一个对象,当另一个对象的特定属性改变的时候,需要被通知到。
    例 如,A对象希望能够觉察到B对象的age属性的任何变化。 

    (2)那么 A必须发送一个“addObserver:forKeyPath:options:context:”消息,注册成为 B属性的观察者。(说 明:“addObserver:forKeyPath:options:context:”方法在指定对象实例之间建立了一个连接。注意,这个连接不是两 个类之间建立的,而是两个对象实例之间建立的。) 

    【被监听对象 addObserver 监听者 forKeyPath 被监听对象的属性 options监视内容(新值或旧值)context额外信息】;

    (3)为了能够响应消息,观察者必须实现 “observeValueForKeyPath:ofObject:change:context:”方法。这个方法实现如何响应变化的消息。在这个方 法里面我们可以跟自己的情况,去实现应对被观察对象属性变动的相应逻辑。 

    (4)假如遵循KVO规则的话,当被观察的属性改变的话,方法 “observeValueForKeyPath:ofObject:change:context:”会自动被调用。

     需要强调的是KVO的回调要被调用,属性必须是通过KVC的方法来修改的,如果是调用类的其他方法来修改属性,这个观察者是不会得到通知的。

    NSNotification:

    1、监听通知

    【center addObserver :监听者 selector:须执行的方法 name:所监听者通知的名称 object:通知发送者】;

    2、通知中心发布消息

    【center PostNotificationName:@“test”object:@"11"】;

    for example:

    - (void)viewDidLoad
    {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(test:) name:@"testNotice" object:@"test"];
        
        [[NSNotificationCenter defaultCenter]postNotificationName:@"testNotice" object:@"test"];
    }
    
    -(void)test:(NSNotification*)noti{
        NSLog(@"name:%@,object:%@",noti.name,noti.object);
        
    }

     总结:KVO与NSNotification

    相同点:都可以通过addObserver 方法来监听,都是能通过监听获得处理

    不同点:触发点不一样   KVO在属性上通过 K-V 发生改变时,自动调用observeValueForKeyPath方法

    而NSNotification 在需要的时候 发送通知才调用,且方法自定义

  • 相关阅读:
    swift 上的 lazy
    oc runtime
    iOS布局
    ios微信支付 v3
    好用的工具
    自己曾经没注意的东西
    根据文字计算出label的高度
    项目swift的一些问题
    UIAppearance
    书签
  • 原文地址:https://www.cnblogs.com/zhangqifeng/p/4018653.html
Copyright © 2011-2022 走看看