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];
// 不能编译

最新文章

  1. mysql游标循环的使用
  2. Linux下查看文件和文件夹大小
  3. Task schedule 分类: 比赛 HDU 查找 2015-08-08 16:00 2人阅读 评论(0) 收藏
  4. unbuntu下vnc和vnc2swf的使用
  5. 进入第一个Android应用界面
  6. 返回到上一页的html代码的几种写法
  7. 文件头 MAGE_FILE_HEADER
  8. Android studio之更改快捷键及自动导包
  9. 404 error on preview ... "buffer_id(29) is not valid (closed or unsupported file format)"
  10. js原生Ajax 的封装和原理
  11. Java数据持久层框架 MyBatis之API学习三(XML 映射配置文件)
  12. 使用hexo搭建个人博客
  13. Cython入门Demo(Linux)
  14. OGG微服务架构入门
  15. jQuery 操作Cookie
  16. python数据类型(二)
  17. Spring MVC异常处理SimpleMappingExceptionResolver
  18. 在 Linux 中使用超级用户权限
  19. DDA画线算法
  20. as3 分发事件无法接收

热门文章

  1. Element-UI 2.4.11 版本 使用注意(发现一点更新一点)
  2. 为什么选择B+树作为数据库索引结构?
  3. 企查查app 初步探索
  4. 逆向破解之160个CrackMe —— 018
  5. N*N矩阵的旋转 不开辟新空间
  6. TomatoLog-1.1.0实现ILoggerFactory
  7. java学习之- 线程运行状态
  8. 以太坊智能合约[ERC20]发币记录
  9. ionic app 监听网络功能
  10. .Net之微信小程序获取用户UnionID