KVO的使用
KVO的使用
KVO是一种设计模式,名为观察者.
addObserver:forKeyPath:options:context:
通知其他对象的方法,这个方法在NSObject中就已经申明了,也就是说任何继承自NSObject的对象都可以使用KVO.
我们来实现一个对象a值改变的时候去通知对象b.
新建两个ModelA ModelB 类.
ModelA.h + ModelA.m
#import Foundation/Foundation.h @interface ModelA : NSObject @property (nonatomic, strong) NSString *name; @end
#import "ModelA.h" @implementation ModelA @end
ModelB.h + ModelB.m
#import Foundation/Foundation.h @interface ModelB : NSObject @property (nonatomic, strong) NSString *sex; @end
#import "ModelB.h" @implementation ModelB -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context self.sex = @"female"; @end
请将如下延时执行的代码添加进工程当中
- (void)delay:(int64_t)delta execute:(dispatch_block_t)block dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delta * NSEC_PER_SEC), dispatch_get_main_queue(), block); }
然后再写如下的代码:
执行结果如下:
2014-05-06 17:40:35.346 FileManager[20208:60b] Application windows are expected to have a root view controller at the end of application launch
2014-05-06 17:40:37.347 FileManager[20208:60b] female
如果注释掉ModelB中的方法observeValueForKeyPath:ofObject:change:context:,运行时会导致崩溃:
如果重复移除了两次,也会导致崩溃-_-!!!!
也就是这么一层关系:
A对象要通知B对象,B对象必须实现监听的方法,否则一旦有消息发送就会导致崩溃.
A对象不想通知B对象了,需要从B对象身上移除掉通知.
要想程序不出现问题,我们需要实现3步.
(主动添加B的通知) A ------- B(不实现一个方法就崩溃)
(主动移除B的通知) A ---X-- B
(重复移除B的通知) A ---X-- B(崩溃)
用起来很恶性,还好,我们可以重复添加B的通知而不崩溃......
问题:在ARC中我们需要移除KVO的observer么?
You should explicitly remove the observer even you use ARC. Create a dealloc method and remove there..
-(void)dealloc {[[NSNotificationCenter defaultCenter] removeObserver:self];}
If you see the method you dont need to call [super dealloc]; here, only the method without super dealloc needed.
你需要非常明确的移除你的通知者,即使是在ARC中.创建一个dealloc方法然后在方法里面移除.
ARC中你不需要调用[super dealloc].
问题:ARC给一个对象添加了observer有可能会导致循环应用什么的么?
You need to call removeObserver, ARC only automates retain counts. removeObserver does not impact the retain count.
你需要调用removeObserver,ARC只是自动管理了retain counts,removeObserver并不影响retain count.(这一点我不确定,有待验证)
问题:当要通知的对象已经nil了,这个通知会自动移除吗?
Observers are not removed automatically. From the NSNotificationCenter Class Reference:
观察者不会自动移除,请查看NSNotificationCenter类的原文引述:
Important: The notification center does not retain its observers, therefore, you must ensure that you unregister observers (using removeObserver: or removeObserver:name:object:) before they are deallocated. (If you dont, you will generate a runtime error if the center sends a message to a freed object.)
很重要:通知中心并不会retain他的观察者,所以,你必须确保你那些对象销毁之前注销掉观察者,否则就会出现错误.
You should therefore call
[[NSNotificationCenter defaultCenter] removeObserver:self];
in your dealloc method if you are not 100% sure that the observer was not removed previously.
addObserver:forKeyPath:options:context:
Registers anObserver to receive KVO notifications for the specified key-path relative to the receiver.
- (void)addObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)optionscontext:(void *)context Parameters anObserverThe object to register for KVO notifications. The observer must implement the key-value observing methodobserveValueForKeyPath:ofObject:change:context:.
keyPathThe key path, relative to the receiver, of the property to observe. This value must not be nil.
optionsA combination of the NSKeyValueObservingOptions values that specifies what is included in observation notifications. For possible values, see “NSKeyValueObservingOptions.”
contextArbitrary data that is passed to anObserver in observeValueForKeyPath:ofObject:change:context:.
iOS开发:KVC与KVO KVC 就是键值编码(key-value-coding),可以直接访问对象的属性,或者给对象的属性赋值。黑魔法之一,很多高级的iOS开发技巧都是基于KVC实现的。 KVO 是键值观察者(key-value-observing)。实现方式:通过对某个对象的某个属性添加观察者,当该属性改变,就会调用”observeValueForKeyPath:”方法,为我们提供一个“对象值改变了!”的时机进行一些操作。
IOS开发-KVO 观察者,观察对象属性的变化,当被观察者该属性发生变化时,观察者会接收到通知,可以在回调函数中做相应的处理
KVO分析 KVO的全称是NSKeyValueObserving,对象采用的一种非正式协议,当其他对象的指定属性发生变化时,通知对象。由于KVO的机制,只对对象的属性起作用,一般继承自NSObject都支持KVO。
KVO解析(一) —— 基本了解KVO解析(二) —— 一个简单的KVO实现KVO解析(三) —— KVO合规性KVO解析(四) —— Faults and KVO Notifications
原文地址:http://ios.jobbole.com/84954/ KVC(Key-value coding)键值编码,单看这个名字可能不太好理解。其实翻译一下就很简单了,就是指iOS的开发中,可以允许开发者通过Key名直接访问对象的属性,或者给对象的属性赋值。