47 (OC)* OC反射机制
Objective-C反射机制:是类似于Java的反射机制,这种动态机制可以让oc语言更加的灵活。这句话是对oc反射机制的初步认识,不过具体的怎么类似于java机制,怎么让oc更加的灵活,还得看下面的内容才能了解。
oc反射机制有三个用途:
1.获得Class
2.检查继承关系
3.动态的调用方法
一、反射
反射,一般表现在字符串和Class转换,字符串和内部方法转换,字符串和属性的转换(取值和赋值)。
1. 获得class
#import "Person.h"
// 1.通过字符串来获得Class
Class className = NSClassFromString(@"Person");
NSLog(@"%@", className);
// 2.直接使用Class来创建 一般情况之下我们都用这种方式创建对象
Person *person = [[Person alloc] init];
NSLog(@"%@", person);
// 通过实例对象获得Class
NSLog(@"%@", [person class]);
// 3.通过类来获得Class
NSLog(@"Person.Class = %@", [Person class])
2.检查继承关系
// NSObject提供的了一下几个方法可供一般(继承于NSObject)的对象直接调用
// 通过对象来判断该对象的Class
Person *person = [[Person alloc] init];
NSLog(@"[person class] = %@", [person class]);
// 判断对象是否为某个类的实例对象
NSLog(@"person是否是Person的实例对象:%d", [person isMemberOfClass:Person.class]);
// 判断实例对象是都为某个类及其子类的实例
NSLog(@"[person isKindOfClass:[person class]] = %d ", [person isKindOfClass:[person class]]);
// 判断的实例对象是否实现了指定的协议
NSLog(@"%d", [person conformsToProtocol:@protocol(UITableViewDelegate)]);
3.动态的调用方法
// 此处希望能动态的调用move方法
// 使用 performSelector: withObject: 动态的调用move:方法
[self performSelector:@selector(move:) withObject:@2];
[self performSelector:NSSelectorFromString(@"move:") withObject:@10];
// 使用objc_msgSend 进行实现方法
objc_msgSend(self, @selector(move:), @4);
objc_msgSend(self, @selector(test:andNum:), @1, @2);
4.字符串和属性的转换
OC中属性的反射通过KVC(Key-Value Coding)机制实现,KVC是一种间接访问对象属性的机制,不直接调用getter 和 setter方法,而使用valueForKey 来替代getter 方法,setValue:forKey来代替setter方法。
之前的一篇博客(http://www.cnblogs.com/rayshen/p/5006619.html),在探讨如何把某个对象进行序列化的时候,其实已经使用到KVC,如果某个类遵循NSCoding协议就能编码成NSData(字节流)。
具体KVC使用的示例为:
Persion *persion = [ [Persion alloc] init ];
//不使用KVC
persion.name = @"shen" ;
//使用KVC的写法
[persion setValue:@"shen" forKey:@"name"];
上面是利用KVC访问类里的某个属性,下面利用KVC直接访问类里的类里的某个属性
//不使用KVC
Persion *persion = [ [Persion alloc] init ];
Phone *phone = persion.phone;
Battery *battery = phone.battery; //使用KVC
Battery *battery = [persion valueForKeyPath: @"phone.battery" ];
对于SetValueForKey,需要小心的是,假如类型匹配错误的情况下,编译会通过,但运行会报错(动态消息机制嘛,能理解)
[persion setValue:[NSNumber numberWithInteger:1] forKey:@"name"];
// 编译并运行,但报错 persion.name = [NSNumber numberWithInteger:1];
// 不能编译
最新文章
- mysql游标循环的使用
- Linux下查看文件和文件夹大小
- Task schedule 分类: 比赛 HDU 查找 2015-08-08 16:00 2人阅读 评论(0) 收藏
- unbuntu下vnc和vnc2swf的使用
- 进入第一个Android应用界面
- 返回到上一页的html代码的几种写法
- 文件头 MAGE_FILE_HEADER
- Android studio之更改快捷键及自动导包
- 404 error on preview ... ";buffer_id(29) is not valid (closed or unsupported file format)";
- js原生Ajax 的封装和原理
- Java数据持久层框架 MyBatis之API学习三(XML 映射配置文件)
- 使用hexo搭建个人博客
- Cython入门Demo(Linux)
- OGG微服务架构入门
- jQuery 操作Cookie
- python数据类型(二)
- Spring MVC异常处理SimpleMappingExceptionResolver
- 在 Linux 中使用超级用户权限
- DDA画线算法
- as3 分发事件无法接收