首页
Web开发
Windows程序
编程语言
数据库
移动开发
系统相关
微信
其他好文
会员
首页
>
其他好文
> 详细
KVC KVO
时间:
2015-03-13 18:43:50
阅读:
180
评论:
0
收藏:
0
[点我收藏+]
标签:
kvc kvo
看了一天的KVC、KVO,我就把网上的资料整理一下吧,如有雷同的地方,勿惊。
1、 KVC
KVC :NSKeyValueCoding的简称,它提供了一种在运行时而非编译时动态访问对象属性与成员变量的方式,也就是说,我们可以用字符串的内容作为属性名称或者成员变量名 称进行访问。这种特性有些类似于其他高级编程语言中的反射。
主要的方法
(setValue:forKey,valueForKey)、setValue:forKeyPath,valueForKeyPath)、setValue: forUndefinedKey:
KVC使用实例
1)简单的存取值
.h文件
#import <Foundation/Foundation.h>
@interface Student : NSObject {
NSString *name;
}
@end
.m文件
#import "Student.h"
@implementation Student
@end
通过kvc实现值的存取操作 ps:绕开了property属性访问机制
#import "Student.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
Student *student = [[[Student alloc]init ]autorelease];
[student setValue:@"张三" forKey:@"name"];
NSString *name = [student valueForKey:@"name"];
NSLog(@"学生姓名:%@",name);
}
return 0;
}
2)通过键路径访问属性
如果要访问一个类中属性的属性呢???看下面例子
.h文件
#import <Foundation/Foundation.h>
@interface Course : NSObject {
NSString *CourseName;
}
@end
.m文件
#import "Course.h"
@implementation Course
@end
在Student中添加Course属性 ,student.h文件中代码如下:
#import <Foundation/Foundation.h>
@class Course;
@interface Student : NSObject {
NSString *name;
Course *course;
}
@end
student.m文件中依然什么都没有实现
在main方法中,我们实验通过键路径访问Course中CourseName的属性
#import "Student.h"
#import "Course.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
Student *student = [[[Student alloc]init ]autorelease];
[student setValue:@"张三" forKey:@"name"];
NSString *name = [student valueForKey:@"name"];
NSLog(@"学生姓名:%@",name);
Course *course = [[[Course alloc]init] autorelease];
[course setValue:@"语文课" forKey:@"CourseName"];
[student setValue:course forKey:@"course"];
NSString *courseName = [student valueForKeyPath:@"course.CourseName"];
NSLog(@"课程名称:%@", courseName);
//也可以这样存值
[student setValue:@"数学课" forKeyPath:@"course.CourseName"];
courseName = [student valueForKeyPath:@"course.CourseName"];
NSLog(@"课程名称:%@", courseName);
}
return 0;
}
3)操作集合
在Student类中加入数组NSArray,用来表示其他的学生。这样我们可以添加多个其他的学生,再用集合操作计算学生的分数,最高分,最低分,平均分等
#import <Foundation/Foundation.h>
@class Course;
@interface Student : NSObject
{
NSString *name;
Course *course;
NSInteger point;
NSArray *otherStudent;
}
@end
.m文件实现不变
在main函数中添加三个学生,添加到数组中,然后求平均分,最高,最低分,学生数量
#import "Student.h"
#import "Course.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
Student *student = [[[Student alloc]init ]autorelease];
[student setValue:@"张三" forKey:@"name"];
NSString *name = [student valueForKey:@"name"];
NSLog(@"学生姓名:%@",name);
[student setValue:@"88" forKey:@"point"];
NSString *point = [student valueForKey:@"point"];
NSLog(@"分数:%@", point);
Student *student1 = [[[Student alloc]init]autorelease];
Student *student2 = [[[Student alloc]init]autorelease];
Student *student3 = [[[Student alloc]init]autorelease];
[student1 setValue:@"65" forKey:@"point"];
[student2 setValue:@"77" forKey:@"point"];
[student3 setValue:@"99" forKey:@"point"];
NSArray *array = [NSArray arrayWithObjects:student1,student2,student3,nil];
[student setValue:array forKey:@"otherStudent"];
NSLog(@"其他学生的成绩%@", [student valueForKeyPath:@"otherStudent.point"]);
NSLog(@"共%@个学生", [student valueForKeyPath:@"otherStudent.@count"]);
NSLog(@"最高成绩:%@", [student valueForKeyPath:@"otherStudent.@max.point"]);
NSLog(@"最低成绩:%@", [student valueForKeyPath:@"otherStudent.@min.point"]);
NSLog(@"平均成绩:%@", [student valueForKeyPath:@"otherStudent.@avg.point"]);
}
return 0;
}
KVC的优点
使用KVC可以大大地减少我们的代码量,当遇到property的时候,可以多想想是否可以KVC来帮助我,是否可以用KVC来重构代码
关于KVC的使用,附上一个很好的文章,相信对你重代码会有很大帮助
http://www.cocoachina.com/industry/20140224/7866.html
2、 KVO
KVO :NSKeyValueObserving, 它是一种观察者模式用于监听property的变化,KVO跟NSNotification有很多相似的地方。
KVO使用实例
当指定的对象的属性被修改了,允许对象接收到通知的机制。每当在类中定义一个监听
如: [self addObserver:self forKeyPath:@"items" options:0 context:contexStr];
当然你还可以监听其他对象的属性变化
[person addObserver:money forKeyPath:@"account" options:0 context:contexStr];
只要当前类中items这个属性发生的变化都会触发到以下的方法。
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context
KVO的优点
当 有属性改变,KVO会提供自动的消息通知。这样的架构有很多好处。首先,开发人员不需要自己去实现这样的方案:每次属性改变了就发送消息通知。这是KVO机制提供的最 大的优点。因为这个方案已经被明确定义,获得框架级支持,可以方便地采用。开发人员不需要添加任何代码,不需要设计自己的观察者模型,直接可以在工程里使用。其次,KV O的架构非常的强大,可以很容易的支持多个观察者观察同一个属性,以及相关的值。
3、关于KVC和KVO
KVC的实现分析
KVC运用了一个isa-swizzling技术。
isa-swizzling就是类型混合指针机制。KVC主要通过isa-swizzling,来实现其内部查找定位的。
isa指针,就是is a kind of的意思,指向维护分发表的对象的类。该分发表实际上包含了指向实现类中的方法的指针,和其它数据。
如下KVC的代码:
[person setValue:@"personName" forKey:@"name"];
就会被编译器处理成:
SEL sel = sel_get_uid ("setValue:forKey:");
IMP method = objc_msg_lookup (person->isa,sel);
method(person, sel, @"personName", @"name");
***
其中:
SEL数据类型:它是编译器运行Objective-C里的方法的环境参数。
IMP数据类型:他其实就是一个 编译器内部实现时候的函数指针。当Objective-C编译器去处理实现一个方法的时候,就会指向一个IMP对象,这个对象是C语言表述的类型。
***
KVC在调用方法setValue的时候
1)首先根据方法名找到运行方法的时候所需要的环境参数。
2)他会从自己isa指针结合环境参数,找到具体的方法实现的接口。
3)再直接查找得来的具体的方法实现。
这样的话前面介绍的KVO实现就好理解了
当一个对象注册了一个观察者,被观察对象的isa指针被修改的时候,isa指针就会指向一个中间类,而不是真实的类。
所以isa指针其实不需要指向实例对象真实的类。所以我们的程序最好不要依赖于isa指针。在调用类的方法的时候,最好要明确对象实例的类名。
这样只有当我们调用KVC去访问key值的时候KVO才会起作用。所以肯定确定的是,KVO是基于KVC实现的。
KVC KVO
标签:
kvc kvo
原文地址:http://blog.csdn.net/u011597585/article/details/44244605
踩
(
0
)
赞
(
0
)
举报
评论
一句话评论(
0
)
登录后才能评论!
分享档案
更多>
2021年07月29日 (22)
2021年07月28日 (40)
2021年07月27日 (32)
2021年07月26日 (79)
2021年07月23日 (29)
2021年07月22日 (30)
2021年07月21日 (42)
2021年07月20日 (16)
2021年07月19日 (90)
2021年07月16日 (35)
周排行
更多
分布式事务
2021-07-29
OpenStack云平台命令行登录账户
2021-07-29
getLastRowNum()与getLastCellNum()/getPhysicalNumberOfRows()与getPhysicalNumberOfCells()
2021-07-29
【K8s概念】CSI 卷克隆
2021-07-29
vue3.0使用ant-design-vue进行按需加载原来这么简单
2021-07-29
stack栈
2021-07-29
抽奖动画 - 大转盘抽奖
2021-07-29
PPT写作技巧
2021-07-29
003-核心技术-IO模型-NIO-基于NIO群聊示例
2021-07-29
Bootstrap组件2
2021-07-29
友情链接
兰亭集智
国之画
百度统计
站长统计
阿里云
chrome插件
新版天听网
关于我们
-
联系我们
-
留言反馈
© 2014
mamicode.com
版权所有 联系我们:gaon5@hotmail.com
迷上了代码!