參考鏈接:http://lizhaoloveit.com/2014/05/11/KVO/
KVO框沟,即:Key-Value Observing,它提供一種機(jī)制拧晕,當(dāng)指定的對(duì)象的屬性被修改后梅垄,則其觀察者就會(huì)接受到通知。簡(jiǎn)單的說(shuō)就是每次指定的被觀察的對(duì)象的屬性被修改后靡馁,KVO就會(huì)自動(dòng)通知相應(yīng)的觀察者了机久。
KVO其實(shí)也是“觀察者”設(shè)計(jì)模式的一種應(yīng)用。這種模式有利于兩個(gè)類間的解耦合胧弛,尤其是對(duì)于 業(yè)務(wù)邏輯與視圖控制 這兩個(gè)功能的解耦合侠畔。
KVO 的具體實(shí)現(xiàn)
具體實(shí)現(xiàn)代碼如下:
import "ViewController.h"
import "Person.h"
@interface ViewController ()
/** p1 */
@property (strong, nonatomic) Person *p1;
@end
@implementation ViewController
-
(void)viewDidLoad {
[super viewDidLoad];
// 1.什么是通知// 3個(gè)對(duì)象
self.p1 = [[Person alloc] init];
self.p1.name = @"p1";// KVO是監(jiān)聽(tīng)對(duì)象的屬性值的改變的
[self.p1 addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
self.p1.name = @"123";
}
// 這個(gè)方法時(shí)屬于 NSObject 類的,任何對(duì)象都可以作為觀察者
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
NSLog(@"監(jiān)聽(tīng)到了%@的%@屬性發(fā)生了改變", object, keyPath);
NSLog(@"%@", change);
}
@end
打印結(jié)果:
2014-05-11 19:55:34.319 KVO和KVC和通知代理[559:109378] 監(jiān)聽(tīng)到了<Person: 0x15ee2baa0>的name屬性發(fā)生了改變
2014-05-11 19:55:34.320 KVO和KVC和通知代理[559:109378] 123
KVO 的實(shí)現(xiàn)原理
KVO 是基于運(yùn)行時(shí)實(shí)現(xiàn)的
isa Class NSKVONotifying_Person 0x000001a12de2f545
上述例子中,當(dāng) p1.name 的值改變時(shí)码党,p1對(duì)象的 isa 指針會(huì)指向 NSKVONotifying_Person,意味著眉厨,在程序運(yùn)行時(shí)兽狭,會(huì)動(dòng)態(tài)生成一個(gè) NSKVONotifying_Person 類,該類繼承于 Person服球,而且該類中也有個(gè) -setName: 方法颠焦,方法中在設(shè)置 name 的同時(shí)實(shí)現(xiàn)了:
-
(void)setName:(NSString *)name
{
[super setName:name];// 這兩個(gè)方法底層會(huì)調(diào)用observer的- (void)observeValueForKeyPath: ofObject: change: context:這個(gè)方法
[self willChangeValueForKey:@"age"];
[self didChangeValueForKey:@"age"];
}