04 KVC|KVO|Delegate|NSNotification区别
一、 iOS 中KVC、KVO、NSNotification、delegate 在实际的编程中运用的非常多,掌握好他们的运行原理和使用场合对于我们程序的开发将会带来事办工倍的效果;
二、 KVC key-Value coding,键值编码,级通过制定的key我们能查找到对应的value,也能给对应的key附上value值。这一点类似于我们的字典查找。比如我们需要查找哪一页的内容,只需要将字典的唯一的页码(也就是key)找到,就能够知道这一页的内容,根据这个字典这一特性,程序猿们发明了Dictionary.
setValueForKey
setValueForUnDefineKey
setValueForKeys
通过这些方法我们可以对指定的key赋值,页可以对类中没有定义的key赋值。
由于这种方式是通过键值查找和赋值的,它不会经过setter和getter方法,同时也可以给id对象进行赋值。
- //定义一个学生类,学生属性中有一个狗类,书类
- #import <Foundation/Foundation.h>
- #import "TRDog.h"
- @interface TRStrudent : NSObject
- {
- @private
- float _score;
- }
- @property(strong,nonatomic)NSString* name;
- @property(strong,nonatomic)TRDog* dog;
- @property(strong,nonatomic)NSArray* allBooks;
- @end
- #import "TRStrudent.h"
- #import "TRBook.h"
- @implementation TRStrudent
- -(instancetype)init
- {
- if (self=[super init]) {
- self.dog=[[TRDog alloc]init];
- TRBook* book1=[[TRBook alloc]init];
- book1.bookname=@"language";
- book1.bookprice=;
- TRBook* book2=[[TRBook alloc]init];
- book2.bookname=@"math";
- book2.bookprice=;
- self.allBooks=@[book1,book2];
- }
- return self;
- }
- @end
- #import <Foundation/Foundation.h>
- #import <UIKit/UIKit.h>
- @interface TRBook : NSObject
- @property(strong,nonatomic)NSString* bookname;
- /*CGFloat可以识别系统的位数*/
- @property(assign,nonatomic)CGFloat bookprice;
- @end
- #import "TRBook.h"
- @implementation TRBook
- @end
- #import <Foundation/Foundation.h>
- @interface TRDog : NSObject
- @property(strong,nonatomic)NSString* name;
- @end
- #import "TRDog.h"
- @implementation TRDog
- @end
- #import "ViewController.h"
- #import "TRStrudent.h"
- @interface ViewController ()
- @end
- @implementation ViewController
- - (void)viewDidLoad {
- [super viewDidLoad];
- TRStrudent* stu=[[TRStrudent alloc]init];
- /*使用KVC为私有的成员变量赋值*/
- [stu setValue:@98.5 forKey:@"score"]; //@98.5将数据进行了封装
- [stu setValue:@"zhangshan" forKey:@"name"];
- NSLog(@"name%@",[stu valueForKey:@"name"]);
- NSLog(@"score%@",[stu valueForKey:@"score"]);
- /*使用KVC为id类型的对象赋值*/
- id stu2=[[TRStrudent alloc]init];
- [stu2 setValue:@"wangwu" forKey:@"name"];
- NSLog(@"name:%@",[stu2 valueForKey:@"name"]);
- /*使用KVC进行层级访问,为学生的Dog对象赋值*/
- [stu.dog setValue:@"旺财" forKey:@"name"];
- NSLog(@"stu.dog name:%@",stu.dog.name);
- /*KeyPath可以访问带有层级关系的属性*/
- [stu2 setValue:@"阿黄" forKeyPath:@"dog.name"];
- NSLog(@"stu2 dongname:%@",[stu2 valueForKeyPath:@"dog.name"]);
- /*可以使用一些关键字快速返回数组中的某些数据,或对数组中的数据进行运算*/
- NSArray* allBookName=[stu valueForKeyPath:@"allBooks.bookname"];
- NSLog(@"%@",allBookName);
- /*所有书的总价格*/
- NSLog(@"%@",[stu valueForKeyPath:@"allBooks.@sum.bookprice"]);
- /*学生一共有几本书*/
- NSLog(@"totalbooks%@",[stu valueForKeyPath:@"allBooks.@count"]);
- }
- - (void)didReceiveMemoryWarning {
- [super didReceiveMemoryWarning];
- // Dispose of any resources that can be recreated.
- }
- @end
-》通过上面的代码不难看出,使用KVC可以对多个包含关系的key值进行层级访问
[stu2 valueForKeyPath:@"dog.name"]
-》使用KVC可以对数组key所包含的keys对应的value 进行函数运算
- [stu valueForKeyPath:@"allBooks.@sum.bookprice"] 对allBooks数组中所有的bookPrice的value价格进行了求和
-》使用KVC可以对数组中的key进行计数
[stu valueForKeyPath:@"allBooks.@count"] allBooks为一个属性数组,包括了多本书。使用.@count进行计数
二、 KVO ,给某个对象的属性keyPath添加观察者,当这个属性发生变化时,检查者能立即知道。常用的的API如下:
1.注册需要观察的对象的属性addObserver:forKeyPath:options:context:
2.实现observeValueForKeyPath:ofObject:change:context:方法,这个方法当观察的属性变化时会自动调用
3.取消注册观察removeObserver:forKeyPath:context:
其本质是在在runtime运行时过程中,系统会自动派生出一个新的类NSKVONotifying_TRSudent,在此类中会改写 keyPath的set方法,在里面添加一个方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context; 所以只需要在父类中写下这个方法的实现过程,当运行子类派生的set方法时候就会自动的执行此方法。
/**
参数一:被观察的对象
参数二:需要观察的对象
参数三:age 需要观察的对象的对应的属性
参数四:一段属性发生该百年,给监控着发送消息需要传递的值,是否是旧值和新值
参数五:发送的额外信息
*/
[self.stu addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:@"又老了一点"];
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
id newValue = [object valueForKey:keyPath];
NSLog(@"%@ 对象的%@属性发生了改变\n,数值如下:旧值是%@,新值是:%@,额外信息%@",object,keyPath,change[@"old"],change[@"new"],context);
}
三、 各自的使用时机:
KVO使用时机: 当用户输入的View界面有个地方改变的时候我们希望model层做出一定的响应并将信息反馈出来。 比如我们在需要确认用户输入的新值和旧值的时候来做一定的计算处理。再比如主任的宠物的血量放生变化的时候主人的攻击受到影响。KVO使用会派生新的类,比较耗费程序资源,一般较少使用。
Delegate使用时机:常用用于界面View点击时间中的交互动作,例如系统UI控件被用户点击或拖拽后会出发一些列的响应事件,类似于这种同类型的业务逻辑之间的响应方式,比较适合使用Delegate.由比如一个类对多个类之间有着同样的业务需求,就好比一个老板需要多个秘书来协同处理它交代的任务,这样的场合也比较适合使用代理。代理方和委托方存在has-a的控制关系,执行效率较高,且刻度性较高,缺点主要是代码累赘,规则繁琐。
Block使用时机:与代理功能相似的还有Block,但他的刻度性较差,尤其是出现多重调用的时候很容易让人混淆,所以长使用Block在单一的两个类之间进行回调,例如登录注册请求工具类,登录注册控制器。 地图定位请求工具类,与主控制器请求定位类。 这种比较单一的,简单单的回调可以使用Block. -》通过对堆区预先注册函数,等到运行到这个block块的时候再调用,使用效率也相对较高,而且比较灵活,缺点可读性差。
NSNotificaiton: 使用实际,它常用于一些系统性的通知,及多个类中都有可能需要对某一信息进行监听,主要是讲通知发送到广播中心,通过第三方媒介广播进行发送通知消息。接收他的对象只需在通知中心进行订阅即可,比较适合于一个控制器要同时监听多个控制器的变化消息。 例如 我们的分类列表栏目里有很多子控制器的分栏列表,当这些个数据发生变化的时候我们需要通知到主控制器进行界面的数据更新,如果都适用协议,就会导致程序编的非常复杂,主控制器中需要遵守各种各样的协议,(如果使用通知,就很方便的管理我们的代码),所有的操作都需要依靠三方来完成,执行效率略逊于代理。
04 KVC|KVO|Delegate|NSNotification区别的更多相关文章
- KVC、KVO、NSNotification、delegate 总结及区别
1.KVC,即是指 NSKeyValueCoding,一个非正式的Protocol,提供一种机制来间接访问对象的属性.而不是通过调用Setter.Getter方法访问.KVO 就是基于 KVC 实现的 ...
- iOS 中KVC、KVO、NSNotification、delegate 总结及区别-b
1.KVC,即是指 NSKeyValueCoding,一个非正式的Protocol,提供一种机制来间接访问对象的属性.而不是通过调用Setter.Getter方法访问.KVO 就是基于 KVC 实现的 ...
- KVC&KVO&NSNotification
KVC,即是指 NSKeyValueCoding,一个非正式的 Protocol,提供一种机制来间接访问对象的属性.KVO 就是基于 KVC 实现的关键技术之一. 一个对象拥有某些属性.比如说,一个 ...
- KVC,KVO详解
Key Value Coding Key Value Coding是cocoa的一个标准组成部分,它能让我们可以通过name(key)的方式访问property, 不必调用明确的property ac ...
- KVC/KVO原理详解及编程指南
一.简介 1.KVC简介 2.KVO简介 二.KVC相关技术 1.Key和Key Path 2.点语法和KVC 3.一对多关系(To-Many)中的集合访问器方法 4.键值验证(Key-Value V ...
- 【转】iOS页面间传值的方式(Delegate/NSNotification/Block/NSUserDefault/单例)-- 不错
原文网址:http://www.cnblogs.com/JuneWang/p/3850859.html iOS页面间传值的方式(NSUserDefault/Delegate/NSNotificatio ...
- 【转】 KVC/KVO原理详解及编程指南
原文地址:http://blog.csdn.net/wzzvictory/article/details/9674431 前言: 1.本文基本不讲KVC/KVO的用法,只结合网上的资料说说对这种技术的 ...
- iOS页面间传值的方式 (Delegate/NSNotification/Block/NSUserDefault/单例)
iOS页面间传值的方式(Delegate/NSNotification/Block/NSUserDefault/单例) iOS页面间传值的方式(NSUserDefault/Delegate/NSN ...
- 转:KVC/KVO原理详解及编程指南
作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/9674431 转载请注明出处 如果觉得文章对你有所帮助,请通过留言或 ...
随机推荐
- C# DataTable中根据某Column值(不重复)获取该值所在行
System.Data.DataTable dt = new System.Data.DataTable(); dt.PrimaryKey = new System.Data.DataColumn[] ...
- oracle字符集相关
转: Database character set (AL32UTF8) and Client character set (ZHS16GBK) are different. Character se ...
- QuickRun-快速运行助手
大家平时需要打开软件的时候都是怎么操作的?一般来说有三种方式: 切换到桌面再点击软件的快捷方式(会将当前正在操作的软件隐藏,再切换回之前的状态比较麻烦,特别是桌面被密密麻麻的图标铺满的时候,找到一个快 ...
- Alwayson 与 mirror
--将主副本改为同步模式和自动故障转移,将其中一个辅助副本改为同步辅助副本和自动故障转移 USE [master]GOALTER AVAILABILITY GROUP [TESTDB5AG]MODIF ...
- java.sql.SQLException: Incorrect key file for table 'C:\Windows\TEMP\#sql578_6e2_68d.MYI'; try to repair it
java.sql.SQLException: Incorrect key file for table 'C:\Windows\TEMP\#sql578_6e2_68d.MYI'; try to re ...
- [原] VS新添加WebApplication项目,无法运行,请求帮助,问题如何解决
最近在WIN10 Pro上安装运行VS2012(安装顺利),新建WebApplication项目,无法运行,编译都无法通过,但都是警告. 症状: 1.新建项目无法编译: 2.新建后,默认引用全部感叹号 ...
- C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0
C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0
- Eclipse断点调试方法
1. 条件断点 断点大家都比较熟悉,在Eclipse Java 编辑区的行头双击就会得到一个断点,代码会运行到此处时停止. 条件断点,顾名思义就是一个有一定条件的断点,只有满足了用户设置的条件,代码才 ...
- logstash输出到influxdb
用了这个logstash扩展 https://github.com/PeterPaulH/logstash-influxdb/blob/master/src/influxdb.rb 把这个文件放到 l ...
- svn版本搭建
安装步骤如下: 1.yum install subversion 2.输入rpm -ql subversion查看安装位置,如下图: 我们知道svn在bin目录下生成了几个二进制文件. 输入 ...