博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS开发基础-KVC简单介绍
阅读量:5041 次
发布时间:2019-06-12

本文共 4793 字,大约阅读时间需要 15 分钟。

一、KVC介绍

  键值编码(Key Value Coding,KVC):使开发者不必进行任何操作就可以进行属性的动态读写。

  KVC操作方法由 NSKeyValueCoding 协议提供,而 NSObject 实现了这个协议,因此 ObjC 中几乎所有的对象都支持KVC操作,常用的操作方法如下:

1)动态设置: setValue:forKey: 用于简单路径, setValue:forKeyPath: 用于复合路径。如 Person 类有一个 Account 类型的属性,那么 Person.Account 就是一个复合属性。

2)动态读取: valueForKey: 、 valueForKeyPath: 。

  补充:键值观察(Key Value Observer,KVO):监听某一个模型的属性,只要该模型属性的值发生变化就通知你。

 

二、代码实例1

  新建 Command Line Tool 项目,并命名为 KVCDemo 。紧接着,为项目添加一个继承自 NSObject 类的 Person 类,为该新类添加名字和年龄属性,如下:

1 //Person.h2 @property (nonatomic, copy) NSString *name;3 @property (nonatomic, assign) int age;

  在 Person 类的实现文件中重写 description 方法:

1 //Person.m2 - (NSString *)description {3     return [NSString stringWithFormat:@"<%@:%p>, {name:%@, age:%d}.", [self class], self, self.name, self.age];4 }

  上述中 %p 指代指针。

  在 main.m 文件中对 Person 进行简单的处理:

1 //main.m 2 int main(int argc, const char * argv[]) { 3     @autoreleasepool { 4         Person *p1 = [[Person alloc] init]; 5         [p1 setValue:@"WJQ" forKey:@"name"]; 6         [p1 setValue:@"23" forKey:@"age"]; 7          8         Person *p2 = [[Person alloc] init]; 9         [p2 setValue:@"LWX" forKey:@"name"];10         [p2 setValue:@"22" forKey:@"age"];11         NSLog(@"%@. %@.", p1, [p2 valueForKey:@"name"]);12     }13     return 0;14 }

  使用 setValue:forKey: 进行KVC操作时,系统会自动判断对象属性的类型并完成转换,如上例将 @"23" 转换为 23 。

  输出为:

, {name:WJQ, age:23}.. LWX.

 

三、代码实例2

  如何生成只包含 name 属性的数组,并打印出来?

  在 main.m 文件中中导入 Person 类的头文件,并修改 main 函数的代码:

1 int main(int argc, const char * argv[]) { 2     @autoreleasepool { 3         Person *p1 = [[Person alloc] init]; 4         [p1 setValue:@"WJQ" forKey:@"name"]; 5         [p1 setValue:@"23" forKey:@"age"]; 6          7         Person *p2 = [[Person alloc] init]; 8         [p2 setValue:@"LWX" forKey:@"name"]; 9         [p2 setValue:@"22" forKey:@"age"];10         11         NSArray *persons = @[p1, p2];   //创建Person对象的数组12         NSLog(@"%@", persons);13         NSMutableArray *arrayM = [NSMutableArray array];    //用于存放各个Person的name14         for (Person *p in persons) {15             [arrayM addObject:[p valueForKeyPath:@"name"]];16         }17         NSLog(@"%@", arrayM);18     }19     return 0;20 }

  输出为:

(    "
, {name:WJQ, age:23}.", "
, {name:LWX, age:22}.")( WJQ, LWX)

  由于使用KVC按键值路径取值时,如果对象不包含指定的键值,会自动进入对象内部,查找对象的属性。在不改变输出的情况下,修改上述代码为:

1 int main(int argc, const char * argv[]) { 2     @autoreleasepool { 3         Person *p1 = [[Person alloc] init]; 4         [p1 setValue:@"WJQ" forKey:@"name"]; 5         [p1 setValue:@"23" forKey:@"age"]; 6          7         Person *p2 = [[Person alloc] init]; 8         [p2 setValue:@"LWX" forKey:@"name"]; 9         [p2 setValue:@"22" forKey:@"age"];10         11         NSArray *persons = @[p1, p2];   //创建Person对象的数组12         NSLog(@"%@", persons);13         NSMutableArray *arrayM = [NSMutableArray array];    //用于存放各个Person的name14         [arrayM addObject:[persons valueForKeyPath:@"name"]];15         NSLog(@"%@", arrayM);16     }17     return 0;18 }

 

三、代码实例3

  演示根据键值路径取值,KVC机制会自动层层深入,并获取对应的键值。

  为项目新建一个 Book 类继承自 NSObject ,添加 bookName 属性:

1 //Book.h2 @property(nonatomic, copy) NSString *bookName;

  修改 Book 类的 description 方法:

1 //Book.m2 - (NSString *)description {3     return [NSString stringWithFormat:@"<%@, %p>, {bookName:%@}", [self class], self, self.bookName];4 }

 

  接着在 Person 类的头文件中导入 Book.h ,再添加一个 Book 类的对象属性,如下:

1 //Person.h2 @property (nonatomic, strong) Book *book;

  修改 Person 类的 description 方法,使其输出 book 属性:

1 //Person.m2 - (NSString *)description {3     return [NSString stringWithFormat:@"<%@:%p>, {name:%@, age:%d, book:%@}.", [self class], self, self.name, self.age, self.book];4 }

 

  最后,修改 main 函数:

1 //main.m 2 int main(int argc, const char * argv[]) { 3     @autoreleasepool { 4         Person *p1 = [[Person alloc] init]; 5         [p1 setValue:@"WJQ" forKey:@"name"]; 6         [p1 setValue:@"23" forKey:@"age"]; 7         Book *b1 = [[Book alloc] init]; 8         b1.bookName = @"iPhone"; 9         p1.book = b1;10         11         Person *p2 = [[Person alloc] init];12         [p2 setValue:@"LWX" forKey:@"name"];13         [p2 setValue:@"22" forKey:@"age"];14         Book *b2 = [[Book alloc] init];15         b2.bookName = @"iOS";16         p2.book = b2;17         18         NSArray *persons = @[p1, p2];   //创建Person对象的数组19         NSLog(@"%@", persons);20         NSArray *arrayM = [persons valueForKeyPath:@"book.bookName"];21         NSLog(@"%@", arrayM);22     }23     return 0;24 }

  输出为:

(    "
, {name:WJQ, age:23, book:
, {bookName:iPhone}}.", "
, {name:LWX, age:22, book:
, {bookName:iOS}}.")( iPhone, iOS)

 

参考博客:

实例代码:

转载于:https://www.cnblogs.com/wjq-Law/p/5135497.html

你可能感兴趣的文章
iOS设计模式 - 中介者
查看>>
centos jdk 下载
查看>>
HDU 1028 Ignatius and the Princess III(母函数)
查看>>
(转)面向对象最核心的机制——动态绑定(多态)
查看>>
token简单的使用流程。
查看>>
django创建项目流程
查看>>
UIActionSheet 修改字体颜色
查看>>
Vue 框架-01- 入门篇 图文教程
查看>>
Spring注解之@Lazy注解,源码分析和总结
查看>>
多变量微积分笔记24——空间线积分
查看>>
Magento CE使用Redis的配置过程
查看>>
poi操作oracle数据库导出excel文件
查看>>
(转)Intent的基本使用方法总结
查看>>
Mac 下的Chrome 按什么快捷键调出页面调试工具
查看>>
Windows Phone开发(24):启动器与选择器之发送短信
查看>>
JS截取字符串常用方法
查看>>
Google非官方的Text To Speech和Speech Recognition的API
查看>>
stdext - A C++ STL Extensions Libary
查看>>
Django 内建 中间件组件
查看>>
bootstrap-Table服务端分页,获取到的数据怎么再页面的表格里显示
查看>>