kvc机制,kvo与kvc

  kvc机制,kvo与kvc

  KVO/KVC摘要

  以下是网上文章的汇总,方便查看。

  在网上阅读别人的文章来了解KVC和KVO。有一个kvo-kvc的例子,就是改变数组的内容(插入和删除),同步改变tableview中的内容。运行完代码,想在添加和修改数组的时候改变tableview的内容,但是一直调用不了observation函数。后来查了一些资料。原来数组的kvc是有固定格式的函数名。将修改后的项目放入资源中。供大家下载。以下是复制的资料。

  一、KVC和KVO的概念1 KVC:NSKeyValueCoding的简称,是一种可以通过字符串的名称(key)直接访问类属性的机制,而不是通过被调用的Setter和Getter方法。

  2 KVO:NSKeyValueObserving的缩写,这种机制允许指定的对象在其属性被修改时接收通知。

  二。KVC简介。概观

  KVC是KeyValue Coding的缩写,这是一种可以通过字符串(键)的名称直接访问类属性的机制。而不是调用Setter和Getter方法。

  KVC是使用KVO、核心数据、协同绑定和AppleScript(Mac支持)时的关键技术。

  2.如何使用KVC

  密钥方法在:NSKeyValueCodingprotocol中定义

  KVC支持类对象和内置的基本数据类型。

  获得价值

  ValueForKey:传入NSString属性的名称。

  ValueForKeyPath:以xx.xx的形式传递给NSString属性的路径

  valueForUndefinedKey的默认实现是引发异常。您可以为错误处理重写该函数。

  修改值

  setValue:forKey:

  setValue:forKeyPath:

  setValue:forUndefinedKey:

  SetNilValueForKey:在非类对象属性上设置nil时,默认情况下调用它并抛出异常。

  一对多关系成员

  MutableArrayValueForKey:有序的一对多关系成员NSArray

  MutableSetValueForKey:无序的一对多关系的成员NSSet

  3.KVC实施细则

  搜索Setter和Getter方法

  这部分比较重要,可以让你知道调用KVC后,如何获取和设置类成员的值。

  搜索简单成员

  例如基本类型成员,单对象类型成员:NSInteger,NSString*成员。

  A.setvalue:forge的搜索方法:

  首先搜索set Key: method。

  如果用@property处理成员,@synthsize,因为@synthsize告诉编译器自动生成set Key形式的setter方法:这种情况下会直接搜索。

  注意:这里的键指的是成员名,首字母大写。下同。

  上面的setter方法没有找到,如果类方法AccessInstanceVariableSDIrectly直接返回YES(注意:这是在NSKeyValueCodingCatogery中实现的类方法,默认实现是返回YES)。

  然后按照_键,_是键,键,是键的顺序搜索成员名。

  如果找到设置成员的值,如果setValue:forUndefinedKey:未被调用。

  B.valueForKey:搜索方法:

  1.首先按照get Key,Key,is Key的顺序找到getter方法,找到直接调用。如果是bool、int等内置值类型,会做NSNumber转换。

  2.找不到上面的getter。查找countOf Key、objectIn Key AtIndex:和Key AtIndexes格式的方法。

  如果找到countOf键和另外两个方法之一,将返回一个可以响应NSArray所有方法的集合代理对象。发送到此代理集合(collectionproxy对象)的NSArray消息方法将以几种方法组合的形式调用:countOf Key、objectIn Key AtIndex:和Key AtIndexes。还有一个可选的get Key :range:方法。

  3.如果还没找到,那么找到countOf Key、enumeratorOf Key、memberOf Key的格式的方法:

  如果这三个方法都找到了,将返回一个可以响应NSSet所有方法的集合代理对象。发送到此代理集合(集合代理对象)的NSSet消息方法将以countOf Key、enumeratorOf Key和memberOf Key的组合形式调用:

  4.还是没有找到,那么如果类方法accessinstancevaluablesdirectly返回YES,那么直接按照_ key,_is key,Key,is Key的顺序搜索成员名。

  5.如果再次找不到,则调用valueForUndefinedKey:

  查找有序集成员,如NSMutableArray。

  MutableArrayValueForKey:搜索方法如下:

  1.在索引:处的关键字中搜索插入对象的格式,从索引:处的关键字中删除对象,或在索引:处插入关键字,在索引:处删除关键字。

  如果找到了至少一个insert方法和至少一个remove方法,还会返回一个可以响应NSMutableArray的所有方法的代理集。然后以insertObject:in Key AtIndex:removeObjectFrom Key AtIndex:insert Key :atIndexes,remove Key AtIndexes:有两个可选接口:用对象替换索引处键中的对象,用键替换索引处的键。

  2.否则,搜索set Key:格式的方法,如果找到,那么发送到代理集合的NSMutableArray最终将调用set Key:方法。

  也就是说,mutableArrayValueForKey取出的代理集合被修改后,用set Key重新赋值:这样效率会低很多,建议实现上面的方法。

  3.否则,如果类方法AccessInstanceVariableSdirectly返回YES,则直接按照_ key,key的顺序搜索成员名。如果找到了,那么发送的NSMutableArray消息方法直接传递给这个成员进行处理。

  4.如果再找不到,调用setValue:forUndefinedKey:

  搜索无序集合成员,如NSSet。

  MutableSetValueForKey:搜索方法如下:

  1.以add Key Object:removeyobject:或add Key:removeykey:的格式搜索方法,如果找到至少一个insert方法和至少一个remove方法,则返回一组可以响应NSMutableSet的所有方法的代理。然后以add Key Object:removeyobject:add Key:removeykey:的组合形式调用发送到这个代理集的NSMutableSet消息方法。还有两个可选接口:相交关键点和设置关键点:

  2.如果reciever是ManagedObejct,则搜索将不会继续。

  3.否则,在set Key: format中搜索方法。如果找到了,那么发送到代理集合的NSMutableSet将最终调用set Key:方法。也就是说,mutableSetValueForKey检索到的代理集被修改后,用set Key重新赋值:这样效率会低很多,建议实现上面的方法。

  4.否则,如果类方法AccessInstanceVariableSdirectly返回YES,则直接按照_ key,key的顺序搜索成员名。如果找到了,那么发送的NSMutableSet消息方法就直接传递给这个成员进行处理。

  5.如果再找不到,调用setValue:forUndefinedKey:

  KVC还提供以下功能

  检查该值的正确性

  KVC提供了属性值确认的API,可以用来检查set的值是否正确,替换不正确的值,或者拒绝设置新值并返回错误原因。

  实现验证方法

  采用以下格式:验证密钥:错误:

  比如:

  -(BOOL)validate name:(id *)io value error:(NSError * *)out error

  {

  //Thenamemustnotbenil和mustbeatleatsttwocharacters long。

  if((* ioValue==nil) ([(ns string *)* ioValuelength]2]){

  if(outError!=NULL){

  ns string * errorString=NSLocalizedStringFromTable(

  @Person snamemustbeatleatsttwocharacters long ,@ Person ,

  @ validation:tooshortname error));

  NSDictionary*userInfoDict=

  [NSDictionarydictionaryWithObject:错误字符串

  forKey:NSLocalizedDescriptionKey];

  * out ERROR=[[[NSErroralloc]initWithDomain:PERSON _ ERROR _ DOMAIN

  代码:人员_无效_姓名_代码

  userInfo:userInfoDict]auto release];

  }

  returnNO

  }

  returnYES

  }

  调用验证方法:

  Validate value: forge key: error:默认实现会搜索validate Key :error:格式的验证方法,找到就调用。如果没有找到,默认返回YES。

  注意内存管理问题。

  集合运算

  set操作是通过将参数传递给valueForKeyPath:来使用的,必须在set上使用(如:array),否则会发生运行时错误。其格式如下:

  Leftpath部分:需要操作对象路径。

  Collectionoperator部分:使用@符号来确定所使用的集合操作。

  Rightpath部分:需要设置的属性。

  1.数据操作

  @avg:平均值

  @count:总数

  @max: max

  @min:最小值

  @sum: total

  确保操作的属性是数值类型,否则运行时会出错。

  2.目标操作

  在数组的情况下

  @ distinctUnionOfObjects:返回指定属性的已消除重复值的数组。

  @ UnionofoObjects:返回指定属性的值的数组,没有重复。

  属性的值不能为空,否则将生成异常。

  3.数组操作

  阵列的阵列盒

  @distinctUnionOfArrays:返回指定属性的已消除重复值的数组。

  @unionOfArrays:返回指定属性的值的数组,没有重复。

  @distinctUnionOfSets:同上,只是返回值是NSSet。

  3.KVC实施情况分析

  KVC使用isa-swizzing技术。Isa-swizzling是类型混合指针机制。KVC主要通过isa- swizzling实现内部搜索和定位。Isa指针,顾名思义,(意思是一种),指向维护分布表对象的类。分布表实际上包含了指向实现类中的方法的指针,以及其他数据。

  例如,下面一行KVC代码:

  [site setValue:@ sitename for key:@ name ];

  将被编译器处理成:

  SEL=SEL _ get _ uid( setValue:forKey:);

  IMP method=objc _ msg _ lookup(site-isa,sel);

  方法(site,sel,@sitename ,@ name );

  首先,介绍两个基本概念:

  (1)SEL数据类型:它是编译器运行Objective-C中方法的环境参数。

  (2)IMP数据类型:实际上是编译器内部实现时的函数指针。Objective-C编译器在处理一个方法的实现时,会指向一个IMP对象,这个IMP对象是用C语言表示的类型(其实Objective-C编译器处理的时候,基本都是用C语言)。

  请参考文章:《Objective-C如何避免动态绑定,而获得方法地址》:http://www.cocoadev.cn/Objective-C/Get-method-address.asp,了解如何找到实现该函数的指针。

  KVC的内部实现非常清晰:当一个对象调用setValue时,(1)首先根据方法名找到运行方法所需的环境参数。(2)他会从他的isa指针结合环境参数找到实现接口的具体方法。(3)找出直接实现的具体方法。

  四。KVO简介

  Kvo是可可的一个重要机制。它提供了一种观察属性变化的方法,这大大简化了代码。这种观察-被观察模型适用于这样的情况,例如,根据A(数据类)的一个属性值的变化,B(视图类)中的一个属性也随之变化。对于崇尚MVC的可可来说,kvo被广泛使用。(这种机制听起来像通知,但是通知需要一个发送通知的对象(通常是notificationCenter)来通知观察者。并且kvo被直接通知给被观察对象。)

  应用kvo时,通常遵循以下流程:

  1注册:

  -(void)add observer:(ns object *)a observer for key path:(ns string *)key path选项:(NSKeyValueObservingOptions)选项上下文:(void*)上下文

  KeyPath是要观察的属性值,options给你观察键值变化的选择,context方便传递你需要的数据(注意这是void类型)。

  2.实现变化的方法:

  -(void)observeValueForKeyPath:(ns string *)对象的密钥路径:(id)对象

  change:(NSDictionary*)更改上下文:(void*)上下文

  Change存储一些改变的数据,比如改变前后的数据;如果注册时上下文不为空,则可以在此处接收上下文。

  这不是很简单吗?kvo的逻辑非常清晰,实现步骤也很简单。

  说到这里,大家都跃跃欲试。然而,在此之前,我们需要了解KVC机制。其实了解kvo的逻辑只是为了帮助你理解。你真正要掌握的不是kvo的实现步骤是什么,而是KVC,因为只有符合KVC标准的对象才能使用kvo(强烈建议想使用kvo的人先了解KVC)。

  KVC是一种间接访问对象(由字符串表示)属性的机制,而不是直接调用对象的访问器方法或直接访问成员对象。

  键是确定对象值的字符串。它通常与访问器方法或变量同名,并且必须以小写字母开头。路径是由“.”分隔的键因为属性值也可以包含属性。例如,我们可以有一个类似person的键或类似key.gender的键路径。

  获取属性值时,可以使用valueForKey:的方法将属性值设置为setValue:forKey:同时,KVC还定义了valueForUndefinedKey:对于未定义的属性值,你可以重载它以获得你想要的实现(补充,KVC定义包含在NSKeyValueCoding的非正式协议中)。

  属性是在O-C 2.0中引入的,我们也可以通过。接线员。让我们直接看一个例子:

  @ property NSInteger number

  instance . number=3;

  [实例集值:[ns number number within integer:3]forKey:@ number ];

  请注意,KVC中的所有值都必须是对象。

  上面描述了如何通过KVC获取/设置属性,下面将说明实现KVC的访问器方法。苹果给出的约定通常是:

  - key:和setKey:(命名约定和setter/getter命名相同)。对于未定义的属性,可以使用setnilvaluework:

  至此,你应该已经掌握了KVC的基本概念。之所以说基本,是因为kvc只涉及单值情况,所以也可以应用于多对多关系,这里就不说了,留给大家自学的空间。

  接下来,我们将以集合为例来练习我们已经掌握的KVC。

  选择array,因为在ios中,经常使用array作为tableview的数据源,有这样一种情况:

  假设我们有n条数据,经过一些运算,在原始数据之后又多了两条记录;或者更新和替换n中的一些数据.除了使用KVC,我们还可以使用reloadData方法或reloadRowsAtIndexPaths。前者的缺点是n很大的话就很大。想象一下,你只添加了几条数据,却要重新加载前面的N条数据。后一种方法的缺点是代码是多余的。你必须一次计算每个indexPath,然后重新加载它,你必须提前考虑在什么情况下数据会被更新。

  如果使用KVC/kvo,这种麻烦就迎刃而解了,你不用担心增加或更新了多少条数据。

  下面以添加数据为例来说明要实现的方法:

  实现insert object:inkyatindex:或insertKey:atIndexes。同时,在kvo中,我们可以通过变化字典了解到发生了什么样的变化,从而进行相应的处理。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • office2010激活密钥大全 怎么永久激活office2010
  • project2010产品密钥免费_project2010激活密钥永久激活码
  • c语言调用退出函数 c语言退出整个程序怎么写
  • c语言中怎么给函数初始化 c语言的初始化语句
  • c语言编写函数计算平均值 c语言求平均函数
  • chatgpt是什么?为什么这么火?
  • ChatGPT为什么注册不了?OpenAI ChatGPT的账号哪里可以注册?
  • OpenAI ChatGPT怎么注册账号?ChatGPT账号注册教程
  • chatgpt什么意思,什么是ChatGPT ?
  • CAD中怎么复制图形标注尺寸不变,CAD中怎么复制图形线性不变
  • cad中怎么创建并使用脚本文件,cad怎么运行脚本
  • cad中快速计算器的功能,cad怎么快速计算
  • cad中快速修改单位的方法有哪些,cad中快速修改单位的方法是
  • cad中心点画椭圆怎么做,cad轴测图怎么画椭圆
  • CAD中常用的快捷键,cad各种快捷键的用法
  • 留言与评论(共有 条评论)
       
    验证码: