开发者社区> 吞吞吐吐的> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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大概就是这些了。

 

 

本文转自老Zhan博客园博客,原文链接:http://www.cnblogs.com/mybkn/archive/2013/05/29/3104166.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
iOS Principle:KVO(下)
iOS Principle:KVO(下)
0 0
iOS Principle:KVO(上)
iOS Principle:KVO(上)
0 0
iOS探索 -- KVO 的原理分析
KVO (key-value-observing) 是一种 键值观察 机制, 它允许当前对象去观察目标对象的某个属性的变化; 当被观察对象的属性发生变化后, 会通过特定方法通知观察者对象属性变化的一些情况内容, 观察者对象拿到变化情况后做出相关操作。
0 0
iOS开发:KVC与KVO
KVC 就是键值编码(key-value-coding),可以直接访问对象的属性,或者给对象的属性赋值。黑魔法之一,很多高级的iOS开发技巧都是基于KVC实现的。 KVO 是键值观察者(key-value-observing)。实现方式:通过对某个对象的某个属性添加观察者,当该属性改变,就会调用”observeValueForKeyPath:”方法,为我们提供一个“对象值改变了!”的时机进行一些操作。
0 0
iOS-底层原理 23:KVO 底层原理
iOS-底层原理 23:KVO 底层原理
0 0
IOS开发-KVO
观察者,观察对象属性的变化,当被观察者该属性发生变化时,观察者会接收到通知,可以在回调函数中做相应的处理
0 0
【iOS 开发】Objective - C 面向对象 - 方法 | 成员变量 | 隐藏封装 | KVC | KVO | 初始化 | 多态(二)
【iOS 开发】Objective - C 面向对象 - 方法 | 成员变量 | 隐藏封装 | KVC | KVO | 初始化 | 多态(二)
0 0
【iOS 开发】Objective - C 面向对象 - 方法 | 成员变量 | 隐藏封装 | KVC | KVO | 初始化 | 多态(一)
【iOS 开发】Objective - C 面向对象 - 方法 | 成员变量 | 隐藏封装 | KVC | KVO | 初始化 | 多态(一)
0 0
IOS学习笔记八(KVO)
IOS学习笔记八(KVO)
0 0
iOS中KVC与KVO的应用解析
iOS中KVC与KVO的应用解析
0 0
文章
问答
文章排行榜
最热
最新
相关电子书
更多
Facebook iOS App技术演化十年之路
立即下载
From Java_Android to Swift iOS
立即下载
深入剖析 iOS 性能优化
立即下载