目录

  • 概述

  • KVC基本技术

  • KVC访问函数

  • KVC搜索顺序

  • KVC集合操作

一、概述

  kvc全名是Key-value coding,kvc是一种通过字符串间接的访问oc对象的属性的一种技术。

  一个oc对象之所以能使用kvc技术,是因为NSObject已经实现了NSKeyValueCoding协议,所以继承NSObject类都能用kvc技术。

  访问函数是指访问oc对象的属性的函数,一般分为setter、getter两种。  

二、KVC基本技术

  前面说过kvc是间接访问oc对象的属性的一种技术,是通过下面4个函数来实现的

  1.setValue:forKey

  2.valueForKey:

  3.setValue:forKeyPath

  4.valueForKeyPath:

  我们可以通过这个例子来了解这4个函数

  假设一个人person养有一只猫cat,这只cat有一个名字name.

  如果要给这个猫改名,可以这样写

[cat setValue:@"猫星人" forKey:@"name"];

  可以这样读取这个猫的名字

NSString * name = [cat valueForKey@"name"];

  当然也可以通过 "那个人" 改那只猫的名字或者读取,这时我们的KeyPath就出场了

[person setValue:@"猫星人" forKeyPath:@"cat.name"];

NSString * name = [person valueForKeyPath:@"cat.name"];

三、KVC访问函数

  访问函数分为getter、setter。当调用valueForKey:的时候会调用getter函数,当调用setValue:forKey的时候会调用setter函数。OC会为@property属性自动添加getter、setter。

  getter函数如下

// name的getter函数
-(NSString *)name{
return @"";
}
// 如果是bool类型的话还可以这样
-(BOLL)isHidden{
return YES;
}

  setter函数

-(void)setName:(NSString *)name{
_name = name;
}  

  值得注意的时Array、MutableArray、Set、MutableSet 的getter函数,它们的getter函数不是一个,而是一套。

  Array的getter函数有下面4个构成

// -(NSUInteger)countOf<Key>
-(NSUInteger)countOfArray{
return ;
}
// -(id)objectIn<Key>AtIndex:(NSInteger)index
-(id)objectInArrayAtIndex:(NSInteger)index{
NSArray * otherData = @[@"A1",@"B1",@"C1"];
return [otherData objectAtIndex:index];
}
// -(NSArray *)<key>AtIndexes:(NSIndexSet *)indexes
-(NSArray *)arrayAtIndexes:(NSIndexSet *)indexes{
NSArray * otherData = @[@"A2",@"B2",@"C2"];
NSArray * result = [otherData objectsAtIndexes:indexes];
return result;
}
// -(void)get<Key>:(NSString **)buffer range:(NSRange)inRange
-(void)getArray:(NSString **)buffer range:(NSRange)inRange{
NSArray * otherData = @[@"A3",@"B3",@"C3"];
for (NSUInteger i=inRange.location; i < inRange.length; i++) {
*(buffer+i)= [otherData objectAtIndex:i];
}
}

   set的getter函数

// -(NSUInteger)countOf<Key>
-(NSUInteger)countOfTestSet{
return ;
}
// -(NSEnumerator *)enumeratorOf<Key>
-(NSEnumerator *)enumeratorOfTestSet{
NSSet * set = [NSSet setWithArray:@[@"set1",@"set2",@"set3"]];
return [set objectEnumerator];
}
// 只检验 ,不调用
// -(NSSet *)memberOf<Key>:(NSSet *)object{
-(NSSet *)memberOfTestSet:(NSSet *)object{
return nil;
}

  mutableArray的getter函数,假设key为testMArray.

-(void)insertObject:(NSString *)object inTestMArrayAtIndex:(NSUInteger)index{
[testMArray insertObject:object atIndex:index];
}
-(void)removeObjectFromTestMArrayAtIndex:(NSUInteger)index{
[testMArray removeObjectAtIndex:index];
}
-(void)insertTestMArray:(NSArray *)array atIndexes:(NSIndexSet *)indexes{
[testMArray insertObjects:array atIndexes:indexes];
}
-(void)removeTestMArrayAtIndexes:(NSIndexSet *)indexes{
[testMArray removeObjectsAtIndexes:indexes];
}
-(void)setTestMArray:(NSMutableArray *)array{
// [testMArray setArray:array];
}

四、KVC搜索顺序

  当调用setValue:forKey、valueForKey:,系统并不是简单的调用getter、setter函数,而是有一套流程顺序。

  setter 函数模板: [set<Key>:]

  getter 函数模板: [_<key>,<key>,get<Key>,_is<Key>,is<Key>]  

  setter的搜索过程比较简单,如下:  

    1.搜索 set<Key>:函数,找到直接调用

    2.如果1找不到,就搜索[_<key>,<key>,_is<Key>,is<Key>]成员变量,找到直接访问成员变量( 类函数accessInstanceVariablesDirectly需要返回YES,默认就是返回YES )  

    3.如果需要就调用setNilValueForKey:

    4.1、2、3 都没有命中就调用 setValue:forUndefinedKey:

  getter的搜索过程

    1.搜索 get<Key>, <key>, is<Key> 函数,找到就直接调用,

    2.如果1找不到,就搜索如下组合 A:[countOf<Key> ,objectIn<Key>AtIndex:]、B:[countOf<Key>,<key>AtIndexes: ] ,如果找到A,B其中一个组合就通过这个组合,返回一个NSArray给 valueForKey:,如果A,B都存在,就以B为准。在A、B存在的情况下 可以实现get<Key>:range: 函数最后修改将要返回的数组。

    3.如果2找不到,就搜索下面三个函数 [countOf<Key>、enumeratorOf<Key>、memberOf<Key>:],如果这三个函数都找到就通过enumeratorOf<Key>返回一个NSSet对象。memberOf<Key>:]只用于检测,不调用?

    4.如果3还没用命中,就搜索 _<key>, _is<Key>, <key>, is<Key> 实例变量,找到就直接访问( 类函数accessInstanceVariablesDirectly需要返回YES,默认就是返回YES )
    5.如果1、2、3、4都没有命中 就调用valueForUndefinedKey:

    

    [objc mutableArrayValueForKey:key] 与 [objc valueForKey:] 类似,但是前者返回的是一个特殊的proxy mutableArray。
    1. A :[insertObject:in<Key>AtIndex:,removeObjectFrom<Key>AtIndex:]
      B :[insert<Key>:atIndexes:,remove<Key>AtIndexes:]
      C :[replaceObjectIn<Key>AtIndex:withObject: ,replace<Key>AtIndexes:with<Key>: ]
      至少实现[一个insert,一个remove]时,当给proxy发送insert movie 消息时,会调用A,或者B的方法,不会给原mutableArray发送消息。
    2.如果A,B都没有实现,就搜索set<Key>:,有就调用(不推荐用)
    3.搜索 _<key> , <key>,搜索到就直接用成员变量
    4.如果3搜索不到就报NSUndefinedKeyException

五、KVC集合操作

  kvc的集合操作是指:当被操作的对象是集合(Array)时可以通过valueForKeyPath函数返回一个被处理过的子集。

  有如下处理行为

  1. max - 集合的最大值
  2. min - 集合的最小值
  3. agv - 集合的平均值
  4. count - 集合的个数
  5. sum - 集合的总数

  概念方面已经没有什么可以介绍的了,我们直接看代码  

self.scores = @[
@{@"name":@"A",@"score":@90},
@{@"name":@"B",@"score":@88},
@{@"name":@"C",@"score":@92},
@{@"name":@"D",@"score":@92},
];
// 只是代码
// 个数
NSLog(@"scores count = %@",[self.scores valueForKeyPath:@"@count"]);
NSLog(@"scores avg = %@",[self.scores valueForKeyPath:@"@avg.score.intValue"]);
NSLog(@"scores max = %@",[self.scores valueForKeyPath:@"@max.score"]);
NSLog(@"scores min = %@",[self.scores valueForKeyPath:@"@min.score.intValue"]);
NSLog(@"scores sum = %@",[self.scores valueForKeyPath:@"@sum.score.intValue"]);

  






KVC 开发详情的更多相关文章

  1. KVO 开发详情

    目录 概念 应用KVO的3个步骤 关联属性的KVO 手动管理KVO通知 一.概念 KVO全称是 Key-Value Observing ,是OC的一种消息发送机制.这个机制是指:假设将B对象注册为A对 ...

  2. iOS 定时器开发详情

    目录 概述 NSTimer performSelector GCD timer CADisplayLink 一.概述 在平时的开发任务中,定时器是我们常用的技术.这一节我们来学习iOS怎么使用定时器. ...

  3. objective-c runtime 开发详情

    目录 概述 对象与类的实质 id与class 继承关系与isa 总结 C函数创建一个OC类 OC类与runtime NSObjectProtocol NSObject NSProxy 一.概述 Obj ...

  4. GCD 开发详情

    目录 一.简介 二.dispatch Queue - 队列 三.dispatch Groups - 组 四.dispatch Semaphores - 信号量 五.dispatch Barriers ...

  5. 如何开发Android Wear应用程序

    Android Wear是连接安卓手机和可穿戴产品的一个平台.自从今年上半年发布以来,Android Wear获得了大量关注,既有来自消费者的关注,也有来自开发商的关注,后者希望自己的应用程序已经准备 ...

  6. 微信小程序开发-概述

    微信小程序开发-概述 一.小程序申请&APPID 登录微信平台申请成为小程序开发者,小程序不可直接使用服务号或订阅号的AppID,需要登录微信公众平台管理后台,在网站的"设置&quo ...

  7. jeecms v9开发资料

    开发文档 . 系统架构概述 本系统核心架构为 FreeMarker+hibernate+Spirng 的 mvc 分层架构. 1.1 分层架构模型 img 1.2 数据流转模型 (前端) img . ...

  8. 教你如何开发一个完败Miracast的投屏新功能

      手机与电视,是陪伴在我们生活最常见,陪伴最长久的智能设备.迅猛发展的移动终端与通信技术,赋予了手机更广阔多元的应用生态,大屏电视则以大视野和震撼影音,弥补了手里方寸带来的视觉局限.而今,手机的延伸 ...

  9. 即时聊天IM之三 XMPP协议客户端库的和Android端框架概述

    合肥程序员群:49313181.    合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入) Q  Q:408365330     E-Mail:egojit@qq.com smack ...

随机推荐

  1. HttpContext.RewritePath

    定义:使用给定路径重写 URL.就是可以跳转到指定的URL. 也可以做为伪静态的跳转.具体如下. 他的重载 ①新建一个页面,放两个链接到另一个页面,注意给的链接 ②在 global.asax 文件中 ...

  2. Spring详解篇之 AOP面向切面编程

    一.概述 Aop(aspect oriented programming面向切面编程),是spring框架的另一个特征.AOP包括切面.连接点.通知(advice).切入点(pointCut) . 1 ...

  3. Objective-c 单例设计模式

    Objective-c 单例设计模式 一.什么是单例模式:(Singleton)      单例模式的意图是是的类的对象成为系统中唯一的实例,提供一个访问点,供客户类共享资源.   二.什么情况下使用 ...

  4. 【学时总结】◆学时·V◆ 逆元法

    ◆学时·V◆ 逆元法 □算法概述□ 逆元运算是模运算中的一个技巧,一般用于解决模运算的除法问题.模运算对于加.减.乘是有封闭性的,即 (a±b)%m=a%m±b%m,以及 (a×b)%m=a%m×b% ...

  5. mac同时安装jdk7和jdk8

    下载地址:http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.h ...

  6. 网络基础-交换机、路由器、OSI7层模型

    第1章 网络基础 1.1 网络的诞生 网络的诞生使命:通过各种互联网服务提升全球人类生活品质. 让人类的生活更便捷和丰富,从而促进全球人类社会的进步.并且丰富人类的精神世界和物质世界,让人类最便捷地获 ...

  7. Spring入门注解版

    参照博文Spring入门一,以理解注解的含义. 项目结构: 实现类:SpringHelloWorld package com.yibai.spring.helloworld.impl; import ...

  8. python中正则表达式在中文字符串匹配时的坑

    之前一直有使用python 正则表达式来做中文字符串或者中英文数字混合的字符串的匹配,发现有不少情况下会匹配失灵或者结果混乱,并且在不同操作系统上匹配结果也不一致,查了很久都不知道是什么原因.今天终于 ...

  9. c++ tie,ignore

    ignore 一个未指定的类型对象,任何值都可以没有影响地赋值给它.通常使用tie来解压一个元组,作为可以忽略的占位符. #include <iostream> #include < ...

  10. 笨小熊 南阳acm62

    笨小熊 时间限制:2000 ms  |  内存限制:65535 KB 难度:2   描述 笨小熊的词汇量很小,所以每次做英语选择题的时候都很头疼.但是他找到了一种方法,经试验证明,用这种方法去选择选项 ...