zoukankan      html  css  js  c++  java
  • iOS: 消息通信中的Notification&KVO

    iOS: 消息通信中的Notification&KVO

    在 iOS: MVC 中,我贴了张经典图:

     

    其中的Model向Controller通信的Noification&KVO为何物呢?

    在功能上说,delegate、Notification以及KVO的功能类似,都是作用于 OC中对象 的消息通信。但三者的使用场景是不同的。

    简单的说Delegate是一种回掉函数,更多的用在一对一的场合,可参考 iphone:delegate机制 ;

    Notification 用得较少,使用Notification Center,类似广播方式,所以更适合一对多的通信;

    KVO,key-Value-Observing,观察者模式,适用于侦听另一对象的属性的变化。

    三者的详细区别可以参考另一博文:http://mobile.51cto.com/iphone-386316.htm

    Notification:

    notification的使用十分简单,直接看代码:

     

    复制代码
        //使用类方法获取实例
        NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    
        //增加2个消息监听,消息名都为logInfo,一个在本对象中监听,监听方法GetInfo;一个在oneobj对象监听,监听方法oneObjHandleInfo。
        [center addObserver:self selector:@selector(GetInfo:) name:@"logInfo" object:nil];
        [center addObserver:oneobj selector:@selector(oneObjHandleInfo:) name:@"logInfo" object:nil];
    
        //发送消息,消息名logInfo,传递数据为一个NSString
        [center postNotificationName:@"logInfo" object:@"00000"];
    复制代码

     

    对应的2个接收方法:

    复制代码
    //本对象中...
    -(void) GetInfo:(NSNotification *) notificaion{
        //取得接受数据并打印
        NSString *data = [notificaion object];
        NSLog(@">> %@",data);
    }
    
    //OneObj对象中...
    -(void) oneObjHandleInfo:(NSNotification*) notification{
        //取得接受数据并打印
        NSString *data = [notification object];
        NSLog(@">>OneOBJ %@",data);
    }
    复制代码

    这样就实现了post一个消息的时候,对应的2个监听者都能收到消失并做出相关处理。最后要注意的是在不用的时候把对应的监听给remove掉。

        [center removeObserver:self name:@"logInfo" object:nil];
        [center removeObserver:oneobj name:@"logInfo" object:nil];

    KVO:

    在看KVO之前,有必要先了解下KVC,即,Key-Value Coding 键值对编程。通过key-value可以方便的存取数据。

    具体的操作简单说就是:setValue:forKey:   valueForKey:

    复制代码
    //book Object
    //.h
    #import <Foundation/Foundation.h>
    @class Author;
    @interface Book : NSObject{
        NSString *name;
        Author *author;
        float price;
        NSArray *relativeBooks;
    }
    @end
    //.m
    #import "Book.h"
    @implementation Book
    @end
    复制代码

     

    复制代码
        Book *book = [[Book alloc] init];
        [book setValue:@"iOS book" forKey:@"name"];
        NSString *name = [book valueForKey:@"name"];
        NSLog(@">> %@",name);
        
        Author *author = [[Author alloc] init];
        [author setValue:@"Zhan" forKey:@"name"];
        [book setValue:author forKey:@"author"];
        
        NSString *authorName = [book valueForKeyPath:@"author.name"];
        NSLog(@">> %@",authorName);
        
        [book setValue:@"100" forKey:@"price"];
        NSLog(@">> %@",[book valueForKey:@"price"]);
        
        Book *book1 = [[Book alloc] init];
        [book1 setValue:@"4" forKey:@"price"];
        Book *book2 = [[Book alloc] init];
        [book2 setValue:@"6" forKey:@"price"];
        
        NSArray *books = [NSArray arrayWithObjects:book1,book2,nil];
        [book setValue:books forKey:@"relativeBooks"];
        NSLog(@">>%@",[book valueForKeyPath:@"relativeBooks.price"]);
    复制代码

    更详细的KVC介绍可以参考: http://marshal.easymorse.com/tech/objc-%E4%BD%BF%E7%94%A8kvc

    KVO是基于kvc实现的,采取的是观察者的模式:

    复制代码
        book4=[[Book alloc] init];
        //增加观察者,为本类,keypath为book中的price对象,所以为price
        [book4 addObserver:self forKeyPath:@"price" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
        //修改值
        [book4 setValue:@"4" forKey:@"price"];
    复制代码
    复制代码
    //回掉方法
    -(void) observeValueForKeyPath:(NSString *)keyPath
                          ofObject:(id)object
                            change:(NSDictionary *)change
                           context:(void *)context{
        NSLog(@"cel back");
        if([keyPath isEqual:@"price"]){
            NSLog(@">>>>>>>price is changed");
            NSLog(@"old price is %@",[change objectForKey:@"old"]);
            NSLog(@"new price is %@",[change objectForKey:@"new"]);
        }
    }
    复制代码

    这样便实现了当对象属性改变时,做出相应反应。

     更详细KVO实现也可以参照:http://blog.csdn.net/yuquan0821/article/details/6646400

    那KVC、KVO内部是如何实现的呢?

        “一个对象在调用setValue的时候,(1)首先根据方法名找到运行方法的时候所需要的环境参数。(2)他会从自己isa指针结合环境参数,找到具体的方法实现的接口。(3)再直接查找得来的具体的方法实现。

        因为KVC的实现机制,可以很容易看到某个KVC操作的Key,而后也很容易的跟观察者注册表中的Key进行匹对。假如访问的Key是被观察的Key,那么我们在内部就可以很容易的到观察者注册表中去找到观察者对象,而后给他发送消息。”

    详细check:http://www.cocoadev.cn/Cocoadev/KVO-20100222-0627.asp

     

    iOS中oc通信的通知和KVO大概就是这些了。

     

     

     

  • 相关阅读:
    【公告】阿里云出现问题:镜像创建的服务器无法启动团队
    上周热点回顾(4.8-4.14)团队
    上周热点回顾(4.1-4.7)团队
    【故障公告】阿里云抢占式实例服务器被自动释放引发的故障团队
    上周热点回顾(3.25-3.31)团队
    上周热点回顾(3.18-3.24)团队
    上周热点回顾(3.11-3.17)团队
    博客园 .NET Core 线下技术交流会 -- 上海站团队
    分区助手是什么?(博主推荐)(图文详解)
    IDEA里点击Build,再Build Artifacts没反应,灰色的?解决办法(图文详解)
  • 原文地址:https://www.cnblogs.com/iOS-mt/p/4244921.html
Copyright © 2011-2022 走看看