KVO、KVC

Key-Value Observing (简写为KVO):当指定的对象的属性被修改了,允许对象接受到通知的机制。每次指定的被观察对象的属性被修改的时候,KVO都会自动的去通知相应的观察者,相当于设计模式中的观察者模式。

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

下面我们写个简单的demo,如何使用KVO

首先定义一个类,声明两个属性,name跟pid;

[objc] view plain copy

  1. @interface DataModel : NSObject
  2. {
  3. NSString *name;
  4. NSString *pid;
  5. }

在controller里

[objc] view plain copy

  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. dm=[[DataModel alloc] init];
  5. [dm setValue:@"daren" forKey:@"name"];
  6. [dm setValue:@"1" forKey:@"pid"];
  7. //注册成为观察者 选项参数指定了发送变更通知时提供给观察者的信息。使用NSKeyValueObservingOptionOld选项可以将初始对象值以变更字典中的一个项的形式提供给观察者。指定NSKeyValueObservingOptionNew选项可以将新的值以一个项的形式添加至变更字典。
  8. [dm addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
  9. testLabel=[[UILabel alloc] init];
  10. [testLabel setFrame:CGRectMake(20, 20, 100, 30)];
  11. [testLabel setBackgroundColor:[UIColor clearColor]];
  12. [testLabel setTintColor:[UIColor blackColor]];
  13. [testLabel setText:[dm valueForKey:@"name"]];
  14. [self.view addSubview:testLabel];
  15. UIButton *testButton=[UIButton buttonWithType:UIButtonTypeRoundedRect];
  16. [testButton setFrame:CGRectMake(20, 100, 100, 70)];
  17. [testButton setTitle:@"测试" forState:UIControlStateNormal];
  18. [testButton addTarget:self action:@selector(testPressed:) forControlEvents:UIControlEventTouchUpInside];
  19. [self.view addSubview:testButton];
  20. }
  21. -(void) testPressed:(id) sender
  22. {
  23. [dm setValue:@"wangzi" forKey:@"name"];
  24. }
  25. -(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(voidvoid *)context
  26. {
  27. if([keyPath isEqualToString:@"name"])
  28. {
  29. testLabel.text = (NSString *)[dm valueForKey:@"name"];
  30. }
  31. }
  32. - (void)dealloc
  33. {
  34. [testLabel release];
  35. [dm removeObserver:self forKeyPath:@"name"];
  36. [dm release];
  37. [super dealloc];
  38. }

上述代码中,我们设置了label的文字会随着datamodel类中的一个key的值变化而变化,这就是KVO的一个简单的运用。但KVO是基于KVC实现的,那什么又是KVC。

KVC:Key-Value Coding,直译是:键值编码。简单来讲,就是给属性设置值的;复杂来讲,根据网上的说法,KVC运用了一个isa-swizzling技术。isa-swizzling就是类型混合指针机制。KVC主要通过isa-swizzling,来实现其内部查找定位的。isa指针,如其名称所指,(就是is a kind of的意思),指向维护分发表的对象的类。该分发表实际上包含了指向实现类中的方法的指针,和其它数据。

比如说如下的第一行KVC的代码,其实和第二行的普通代码是等效的:

[myClass setValue:@"daren" forKey:@"name"];

myClass._name = @"daren";

KVC的代码会被编译器处理成:

SEL sel = sel_get_uid ("setValue:forKey:");
IMP method = objc_msg_lookup (myClass->isa,sel);
method(site, sel, @"daren", @"name");

这下KVC内部的实现就很清楚的清楚了:一个对象在调用setValue的时候:

a.  首先根据方法名找到运行方法的时候所需要的环境参数。

b.  它会从自己isa指针结合环境参数,找到具体的方法实现的接口。

c.  再直接查找得来的具体的方法实现。

和notification的区别也是在,KVO是对象之间直接的交互,而notification需要notificationCenter来做为中间交互。

以上都是一些比较浅的理解,更深层次的原理,还需要大家来补充~~~~

时间: 2024-12-21 10:12:56

KVO、KVC的相关文章

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 中KVC、KVO、NSNotification、delegate 总结及区别-b

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

NotificationCenter、KVC、KVO、Delegate

简述NotificationCenter.KVC.KVO.Delegate?并说明它们之间的区别?Notification 是观察者模式的实现,KVO是观察者模式的OB-C底层实现.NOtification 通过 Notifydcation addobserver 和 remove observer 工作. KVO是键值监听,键值观察机制,提供了观察某一属性变化的方法 KVC是键值编码,是一种间接访问对象的属性,使用字符串来标示属性(例如:setValue:forKey:) Delegate:把

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

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

iOS开发——实用篇&KVO与KVC详解

KVO与KVC详解 由于ObjC主要基于Smalltalk进行设计,因此它有很多类似于Ruby.Python的动态特性,例如动态类型.动态加载.动态绑定等.今天我们着重介绍ObjC中的键值编码(KVC).键值监听(KVO)特性: 键值编码KVC 键值监听KVO 键值编码KVC 我们知道在C#中可以通过反射读写一个对象的属性,有时候这种方式特别方便,因为你可以利用字符串的方式去动态控制一个对象.其实由于ObjC的语言特性,你根部不必进行任何操作就可以进行属性的动态读写,这种方式就是Key Valu

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

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

[精辟]KVO 和 KVC 的区别和用法,干货!!!

一.KVO介绍 KVO就是观察者模式,说白了就是你关心的一个值改变了,你就会得到通知.你就可以在你想处理的地方处理这个值. 二.KVO的使用 一般分为三步: 注册监听 使用方法: /** * 添加KVO监听者 * * @param observer 观察者(监听器) * @param keyPath 属性名(要观察的属性) * @param options * @param context 传递的参数 */ - (void)addObserver:(NSObject *)observer for

设计模式之观察者模式(关于OC中的KVO(Observer)\KVC\NSNotification)

学习了这么久的设计模式方面的知识,最大的感触就是,设计模式不能脱离语言特性.近段时间所看的两本书籍,<大话设计模式>里面的代码是C#写的,有一些设计模式实现起来也是采用了C#的语言特性(C#的API,抽象类,在OC中是没有抽象类.没有多继承关系),<设计模式之禅>里面的代码是JAVA写的,与OC差距也是比较大. 但是我想,这些都不是问题,学习设计模式主要学习的是其中的思想,并将之改造成自己所熟悉语言的模式,大同小异.所需要注意的是,在学习的过程中,将之与语言结合起来,多思考.多实践

iOS彩票项目--第七天,初次读取json数据、KVC转模型技巧、运行时字典转模型以及初步对显示网页的操作并且跟踪标签

一.初次读取json数据 二.KVC转模型技巧,这里的技巧主要解决的是字典中的key 与 模型中有的属性对应不起来的时候 的解决办法 <方法1> <方法2>运行时字典转模型,运行时自己一直很晕.不过还是整理下来,方便以后用. 这里直接创建了一个分类. 头文件代码 1 // 2 // NSObject+Model.h 3 // Chaos_G 4 // 5 6 #import <Foundation/Foundation.h> 7 8 @interface NSObjec