ios 中 KVO

KVO(Key value observe)键值观察,是ios中的一种核心的概念,简单的理解为当某一个对象A(或者多个对象)要想监听对象的B的一个或者多个属性发生变化时,就是用这种机制。

  1. KVO的优点

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

2、缺点,实时监听对象属性值的改变,非常消耗系统的性能。

KVO 的面试题。

1、NSNotification和KVO的区别和用法是什么?什么时候应该使用通知,什么时候应该使用KVO,它们的实现上有什么区别吗?如果用protocol和delegate(或者delegate的Array)来实现类似的功能可能吗?如果可能,会有什么潜在的问题?如果不能,为什么?

答:KVO只能监测属性的变化,通过NSString类型的属性名来实现。但是实现了自动监测,当属性值变化时,会自动通知观察者,不用再添加代码了。

NSNotification比较灵活,可以监测的内容较多,但是需要被观察者手动发送通知,观察者才能响应。

protocol通过添加一个NSArray也能实现类似的功能,但是实现上需要自己处理delegate的添加与删除,自己在属性变化时手动通知,较繁琐,易出错

通知机制简介

/**

*  NSNotificationCenter 两个对象之间传递消息,或者多个对象之间传递消息

*  a 对象触发了某个事件(a对象不能完成),需要b对象完成,a对象(void)postNotificationName:(NSString *)aName object:(id)anObject;

*  postNotificationName 发送消息的名字

*  object 发送给哪个对象

*  - (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject; 谁接收通知,接收到通知后实现的方法(SEL)aSelector

*  removeObserver移除通知

*/

下面的KVO的Demo代码:

  1 Person.h内容
  2
  3 #import <Foundation/Foundation.h>
  4
  5 @interface Person : NSObject
  6
  7 @property (nonatomic , copy) NSString *name;
  8 @property (nonatomic , assign) int  age;
  9
 10 //- (void)dogNameChange;
 11
 12 //- (void)dogAgeChange;
 13
 14 @end
 15
 16
 17 Person.m文件内容
 18 #import "Person.h"
 19
 20 @implementation Person
 21
 22 //监听者实现方法
 23 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
 24 {
 25     if ([keyPath isEqual:@"name"]) //dog的name属性改变了
 26     {
 27         NSLog(@"Dog - name- change,old:%@ ,new:%@;context = %@",[change objectForKey:NSKeyValueChangeOldKey],[change objectForKey:NSKeyValueChangeNewKey],context);
 28
 29     }
 30
 31     if ([keyPath isEqual:@"age"]) //dog的age属性改变了
 32     {
 33         NSLog(@"Dog - age - change,old:%@ ,new:%@;context = %@",[change objectForKey:NSKeyValueChangeOldKey],[change objectForKey:NSKeyValueChangeNewKey],context);
 34     }
 35 }
 36
 37 //- (NSString *)description
 38 //{
 39 //    return [NSString stringWithFormat:@"name - %@, age - %d",self.name,self.age];
 40 //}
 41 //
 42 //
 43 //- (void)dogNameChange
 44 //{
 45 //    NSLog(@"dogNameChange");
 46 ////    [self removeObserver:self forKeyPath:@"name"];
 47 //}
 48 //
 49 //- (void)dogAgeChange
 50 //{
 51 //     NSLog(@"dogAgeChange");
 52 //}
 53
 54 @end
 55
 56 Dog.h内容
 57
 58 #import <Foundation/Foundation.h>
 59
 60 @class Person;
 61 @interface Dog : NSObject
 62
 63
 64 @property (nonatomic , weak) Person *onwer;
 65 @property (nonatomic , assign) NSInteger age;
 66 @property (nonatomic , copy) NSString *name;
 67
 68 @end
 69
 70 Dog.m内容
 71
 72 #import "Dog.h"
 73
 74 @implementation Dog
 75
 76
 77 @end
 78
 79 ViewController.m内容
 80
 81 #import "SDViewController.h"
 82 #import "Person.h"
 83 #import "Dog.h"
 84
 85 @implementation SDViewController
 86
 87 - (void)viewDidLoad
 88 {
 89     [super viewDidLoad];
 90      Person *p = [[Person alloc] init];
 91     p.name = @"张三";
 92     p.age = 18;
 93
 94     Dog *d = [[Dog alloc] init];
 95     d.age = 10;
 96     d.name = @"老狗";
 97
 98      //KVO演练 -- 监听某个对象属性的改变
 99     [d addObserver:p forKeyPath:@"age" options:(0x01 | 0x02) context:@"helloage"];
100     [d addObserver:p forKeyPath:@"name" options:(0x01 | 0x02) context:@"helloname"];
101
102     //KVC赋值
103     [d setValue:@(28) forKeyPath:@"age"];
104     [p setValue:@"李四" forKeyPath:@"name"];
105     [p setValue:@(10) forKeyPath:@"age"];
106     [d setValue:@"小狗狗" forKeyPath:@"name"];
107
108 //    [d removeObserver:p forKeyPath:@"name"]; //移除KVO
109 //    [d removeObserver:p forKeyPath:@"age"]; //移除KVO
110
111
112 }

KVO中的头文件中重要的方法简介

/*由于接收器已经被注册为在相对于物体的关键路径价值的观察者,被通知更改该值。 

变更字典总是包含NSKeyValueChangeKindKey项,其值是一个NSNumber包装的NSKeyValueChange(使用 - [NSNumber的unsignedIntegerValue])。 NSKeyValueChange的意义取决于什么样的属性和关键线路识别:
     - 对于任何类型的属性(属性,以一对一的关系,或有序或无序的一对多关系)NSKeyValueChangeSetting表示该观察对象已经收到了-setValue:forKey:消息,或者说,键 - 值编码兼容的设置方法密钥已被调用,或者一个-willChangeValueForKey:/ - didChangeValueForKey:对以其他方式被调用。
     - 对于_ordered_一对多的关系,NSKeyValueChangeInsertion,NSKeyValueChangeRemoval和NSKeyValueChangeReplacement表明,突变的消息已发送到由-mutableArrayValueForKey返回的数组:发送给对象的消息,或者发送到由-mutableOrderedSetValueForKey返回的有序集合:消息发送给对象,或者说,键值中的一个编码标准的阵列或有序集合突变方法的关键已被调用,或者一个-willChange:valuesAtIndexes:forKey:/ - didChange:valuesAtIndexes:forKey:对有否则被调用。
     - 对于_unordered_一对多的关系,NSKeyValueChangeInsertion,NSKeyValueChangeRemoval和NSKeyValueChangeReplacement(在Mac OS10.4中引入)表明,突变的消息已发送到由-mutableSetValueForKey返回的集合:发送给对象的消息,或那一个键 - 值编码兼容的一套基因突变的方法对密钥已被调用,或者一个 -willChangeValueForKey:withSetMutation:usingObjects:/-didChangeValueForKey:withSetMutation:usingObjects:对了,否则被调用。 

对于任何形式的财产,变更字典有一个NSKeyValueChangeNewKey项,如果NSKeyValueObservingOptionNew在观察者注册时指定,这是正确的一种变化,这是不是事先通知。变更字典包含NSKeyValueChangeOldKey如果指定NSKeyValueObservingOptionOld,这是正确的一种变化。请参阅该NSKeyValueObserverNotification非正式协议的方法是什么这些条目的值可以是评论。 

对于一个_ordered_一对多的关系,变更字典总是包含一个NSKeyValueChangeIndexesKey条目的值是包含插入,删除或替换的对象的索引,除非该变化是NSKeyValueChangeSetting一个NSIndexSet。 

如果NSKeyValueObservingOptionPrior(中的Mac OS10.5引入)指定在观察者登记时间,而该通知是一个先前被发送到的变化,结果,变更字典包含NSKeyValueChangeNotificationIsPriorKey项,其值被一个NSNumber包装纸是(用 - [NSNumber的boolValue])。 

背景始终是在观察者报名时间的推移,在同一个指针。*/

//监听者实现方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
//注册观察者 -- observer  谁在监听, keyPath  -- 监听哪一个属性值  options -- 新的值与旧的值   context -- 传送给observer 的消息
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;
//移除观察者
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(void *)context NS_AVAILABLE(10_7, 5_0);
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

  

时间: 2024-11-01 07:27:03

ios 中 KVO的相关文章

IOS中KVO模式的解析与应用

最近老翁在项目中多处用到了KVO,深感这种模式的好处.现总结如下: 一.概述 KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知.简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了. KVO其实也是“观察者”设计模式的一种应用.我的看法是,这种模式有利于两个类间的解耦合,尤其是对于 业务逻辑与视图控制 这两个功能的解耦合. 二.引子 先来看个引子: 有一个业务类:Walker,在这个类内部只负责关于

iOS 中KVO的那点事

今天遇到点关于KVO小问题,纠结了半天.结果是出来了. 需求:监听UITableView数据的变化,一旦变化,就刷新UITableView. 很显然要用到KVO.数据是放到 @property (nonatomic, strong) NSMutableArray* data; 刚开始我是这么做的: 1,注册监听 - (void)viewDidLoad { [super viewDidLoad]; //KVO监听data的变化 [self addObserver:self forKeyPath:@

iOS中KVO使用理解

什么是KVO KVO<NSKeyValueObserving>,是一个非正式协议,提供了一个途径,使对象(观察者)能够观察其他对象(被观察者)的属性,当被观察者的属性发生变化时,观察者就会被告知该变化. 基本使用 添加观察者: - (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable v

iOS 中KVC、KVO、NSNotification、delegate 总结及区别

iOS 中KVC.KVO.NSNotification.delegate 总结及区别 1.KVC,即是指 NSKeyValueCoding,一个非正式的Protocol,提供一种机制来间接访问对象的属性.而不是通过调用Setter.Getter方法访问.KVO 就是基于 KVC 实现的关键技术之一. Demo: @interface myPerson : NSObject { NSString*_name; int      _age; int      _height; int      _w

iOS中消息的传递机制(KVO、Notification、delegation、block以及target-action)---转载

注1:本文由破船[博客]译自Communication Patterns. 本文目录如下所示: 可用的机制 做出正确的选择 Framework示例 小结 每个应用程序或多或少,都由一些松耦合的对象构成,这些对象彼此之间要想很好的完成任务,就需要进行消息传递.本文将介绍所有可用的消息传递机制,并通过示例来介绍这些机制在苹果的Framework中如何使用,同时,还介绍了一些最佳实践建议,告诉你什么时机该选择使用什么机制. 虽然这一期的主题是关于Foundation Framework的,不过本文中还

iOS中NSNotification、delegate、KVO三者之间的区别与联系?

iOS中NSNotification.delegate.KVO三者之间的区别与联系? delegate.notification和KVO他们的功能比较类似,那么在实际的编程中,如何选择这些方式呢? 在开发ios应用的时候,我们会经常遇到一个常见的问题:在不过分耦合的前提下,controllers间怎么进行通信.在IOS应用不断的出现三种模式来实现这种通信: 1.委托delegation: 2.通知中心Notification Center: 3.键值观察key value observing,K

【转载】iOS中delegate,notification,KVO三种模式实现通信的优缺点

原帖地址:http://blog.csdn.net/yangxt/article/details/8176636 在开发iOS中,有三种模式来实现controller之间的通信: 1.委托delegation: 2.通知中心Notification Center: 3.键值观察key value observing,KVO 因此,那为什么我们需要这些模式以及什么时候用它以及什么时候不用它. 1.delegate 基本特征: 一 个controller定义了一个协议(即一系列的方法定义).该协议描

【原】iOS下KVO使用过程中的陷阱

======================================================= 原创文章,转载请注明 编程小翁@博客园,邮件[email protected],欢迎各位与我在C/C++/Objective-C/机器视觉等领域展开交流! ======================================================= KVO,全称为Key-Value Observing,是iOS中的一种设计模式,用于检测对象的某些属性的实时变化情况并作

iOS开发-KVO的奥秘

iOS开发-KVO的奥秘 字数2933 阅读3842 评论28 喜欢57 序言 在iOS开发中,苹果提供了许多机制给我们进行回调.KVO(key-value-observing)是一种十分有趣的回调机制,在某个对象注册监听者后,在被监听的对象发生改变时,对象会发送一个通知给监听者,以便监听者执行回调操作.最常见的KVO运用是监听scrollView的contentOffset属性,来完成用户滚动时动态改变某些控件的属性实现效果,包括渐变导航栏.下拉刷新控件等效果. 渐变导航栏 使用 KVO的使用