美文网首页OC进化iOS Developer17
KVC和runtime的巧妙结合

KVC和runtime的巧妙结合

作者: 大脸猫l | 来源:发表于2017-02-22 17:59 被阅读121次

KVC简介

1.按照官方说明
Key-value coding is a mechanism for indirectly accessing an object’s attributes and relationships using string identifiers.
即KVC键值编码是通过使用字符串标识来访问一个对象的属性的一种机制,这种属性也可以是对象的私有变量,下面再说什么是字符串标识
2.一个对象的属性大致分为三种,官方说明


属性的种类

第一种是简单的foundation属性,例如字符串、整型和Boolean型等
第二种是将自定义的类的对象作为自己的属性,如示例中的Person类(一对一关系)
第三种就是集合类,如数组或者字典等(一对多关系)
我们知道,可以通过setter方法来为这些属性赋值,但是官方文档里面提出这样是不灵活的,看图中线段


官方文档
3.看KVC是如何给属性赋值的
首先看KVC能访问属性的范围
官方文档
从官方图例可以看出,通过KVC,一个对象不仅能访问其属性,也能访问其多级属性,也就是属性的属性

再看赋值方法

KVC赋值方法

从官方文档可以看出,KVC给其属性赋值的方式是
[object setValue:value forKey:@"keyName"];
keyName也就是上面所说的string identifiers,且必须是如此形式,keyName要与该对象的变量名保持一致

从线段所指位置可以看出,对象给其多级属性赋值时要用"."语法访问其
[object setValue:value forKeyPath:@"keyName"];

4.KVC赋值方法


KVC赋值方法

值得注意的是,如果string identifiers找不到,程序便会crash,解决方法是重写图例中的setValue:forUndefinedKey:方法

5.KVC取值方法


取值方法

同样,如果string identifiers找不到,程序便会crash,解决方法是重写图例中的valueForUndefinedKey:方法

6.任何对象为何能通过KVC机制来给属性赋值


非正式协议KVC

第一句已经指出,该机制是通过非正式协议来完成的,非正式协议即给NSObject添加一个Category

进入KVC

上面是官方文档对KVC的一些阐述,下面看KVC的一些方法
首先是修改值

setValue:forKey://给其一级成员变量赋值
setValue:forKeyPath://通过键路径给其多级变量赋值
setValue:forUnderfinedKey://如果未找到同名的string identifiers,则重写该方法,否则报错
setNilValueForKey: //value设置为nil时调用,系统默认调用,不会报错

其次是取值

valueForKey: //通过string identifiers取出通过setValue:forKey:所设置的值
valueForKeyPath: //同上
valueForUndefinedKey: //如果未找到同名的string identifiers,则重写该方法,否则报错

KVC访问属性顺序

@property (nonatomic, copy) NSString *name;
{
    NSString *_name;
    NSString *name;
}

KVC通过遍历所有的成员变量,逐个访问,先查找setName,直接调用,给name属性赋值,如果没有setName,继续寻找_name,最后是name,如果重写了

//默认返回YES
+ (BOOL)accessInstanceVariablesDirectly

并且返回NO,那么,如果找不到setName方法会直接调用

setValue:forUnderfinedKey:

KVC与runtime结合

举个例子,我们想要获取某个控件的私有变量,例如获取UISearchBar的_searchField私有变量,继而去更改UISearchBar输入框的样式等,但是通过官方给的API又无法获取,此时runtime就发挥作用了,如果第一种无法获取到,尝试第二种
第一种(父类属性是不会被遍历出来的)

unsigned int count,i;
//runtime获取UISearchBar属性列表
objc_property_t *propertyArray = class_copyPropertyList([UISearchBar class], &count);
NSMutableArray *array = [NSMutableArray array];
for (i = 0; i < count; i++) {
      objc_property_t property = propertyArray[i];
      NSString *proKey = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
      [array addObject:proKey];
 }
 NSLog(@"%@",array);
 free(propertyArray);//c语言释放内存函数

第二种

unsigned int count,i;
Ivar *propertyArray = class_copyIvarList([UISearchBar class], &count);
NSMutableArray *array = [NSMutableArray array];
for (i = 0; i < count; i++) {
       Ivar property = propertyArray[i];
      NSString *proKey = [NSString stringWithCString:ivar_getName(property) encoding:NSUTF8StringEncoding];
      [array addObject:proKey];
 }
 NSLog(@"%@",array);
 free(propertyArray);

通过打印结果,第二种方式获取到了_searchField
实际操作时是要结合UI效果调试的,比如更改UISearchBar的输入框背景色,看了UISearchBar的结构,内部包含了一个UITextField,一开始肯定不知道该UITextField就是_searchField,在获取到UISearchBar属性列表后,是要慢慢调试的,获取到该属性之后就可以使用KVC赋值了

在xib中也可以使用runtime和KVC更改控件UI

xib runtime使用

点击+号,一看便知怎么用了

相关文章

  • KVC和runtime的巧妙结合

    KVC简介 1.按照官方说明Key-value coding is a mechanism for indirec...

  • 面试问题总结

    Runtime理解。 Runloop理解,结合计时器。 GCD常用的方法。 GCD的原理。 KVO和KVC的实现原...

  • RunTime结合KVC简单使用

    有时候我们需要使用控件的一些私用属性来方便我们的开发, 例如改变UITextField的placeholder文字...

  • [iOS]访问私有变量

    访问对象私有变量的方法有两中 KVC 和 Runtime机制 今天主要说一下KVC吧,runtime有时间单独...

  • 如何访问并修改一个类的私有属性

    通过KVC 通过runtime

  • YYModel源码解析

    闲来无事分析了一下YYModel的源码,以为内部使用KVC实现的,但是结合代码看来是使用了runtime的msg_...

  • iOS KVC/KVO

    1.KVC底层是通过runtime对method和value操作 比如说如下的一行KVC的代码: [sit set...

  • 4.iOS开发之KVC

    iOS的日常开发中KVC与KVO还是使用率蛮高的,整理一下。KVC和KVO都是基于OC的动态特性和Runtime机...

  • 5.iOS开发之KVO

    iOS的日常开发中KVC与KVO还是使用率蛮高的,整理一下。KVC和KVO都是基于OC的动态特性和Runtime机...

  • 字典转模型(KVC+runtime两种方法)

    先说说KVC和runtime两种方法的区别 KVC:遍历字典中的所有key,去模型中查找有没有对应的属性,每个mo...

网友评论

    本文标题:KVC和runtime的巧妙结合

    本文链接:https://www.haomeiwen.com/subject/cklpwttx.html