一、反射

反射,一般表现在字符串和Class转换,字符串和内部方法转换,字符串和属性的转换(取值和赋值)。

二、Objective-C中的反射

OC的反射是基于其Runtime实现的。

以执行某个函数为例,我们知道在OC中执行[Stu doSomething]函数,实质上是发送了一个消息给Runtime,然后Runtime再根据这个Class的字符串名和这个函数的字符串名,去匹配真正相应的方法的地址,然后再执行的。所以中间我们可以利用字符串去动态的检测,甚至动态的修改(之前说到的Method Swizzling)。

在OC中,很多Runtime的动态特性的接口大致都已经在NSObject.h中声明,可以自己看下源码。

反射具体表现在:

1.字符串和Class转换,及判断

Class __nullable NSClassFromString(NSString *aClassName);
-(BOOL)isKindOfClass:(Class)aClass;
-(BOOL)isMemberOfClass:(Class)aClass;

示例:

//通过这样的方式获取class
Class name = NSClassFromString(@"Student");
Student *stu = [[name alloc] init];

//判断是否为其子类的对象
Student *stu = [[Student alloc]init];
if([stu isKindOfClass:[Person class]]){
NSLog(@"stu是Person类型或其子类");
}else{
NSLog(@"stu不是Person类型或其子类");
}
//判断是否是该class的对象
if([stu isMemberOfClass:[Person class]]){
NSLog(@"stu是Person类型");
}else{
NSLog(@"stu不是Person类型");
}

2.字符串和内部方法转换

- (BOOL)respondsToSelector:(SEL)aSelector  判断类型或对象有没有某个方法
+ (BOOL)instancesRespondToSelector:(SEL)aSelector; //判断静态方法
- (id)performSelector:(SEL)aSelector  动态调用对象的方法
- (BOOL)conformsToProtocol:(Protocol *)aProtocol; 判断对象是否实现某个Protocol协议

示例:

//动态生成方法选择器
SEL sel = NSSelectorFromString(@"setAge:"); //检测是否存在某方法
Student *stu = [[Student alloc]init];
if([stu respondsToSelector:@selector(setAge)]){
NSLog(@"stu 有setAge这个方法");
}else{
NSLog(@"没有");
} //动态动用方法
Student *stu = [[Student alloc]initAge:];
int age = [stu performSelector:@selector(age)];
NSLog(@"%i",age);//输出1 //动态调用有参数的方法
[stu performSelector:@selector(setAge1:) withObject:@""];

3.字符串和属性的转换

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:] forKey:@"name"];
// 编译并运行,但报错 persion.name = [NSNumber numberWithInteger:];
// 不能编译

参考博客:

http://blog.csdn.net/victormokai/article/details/19631359

http://www.tuicool.com/articles/2aYfy2

http://www.cnblogs.com/ygm900/archive/2013/01/16/2862676.html

http://www.cnblogs.com/yjmyzz/archive/2011/02/28/1967451.html

http://www.cnblogs.com/yaski/archive/2009/04/05/1429735.html

Objective-C 中基于RunTime实现的反射的更多相关文章

  1. Struts2中基于Annotation的细粒度权限控制

    Struts2中基于Annotation的细粒度权限控制 2009-10-19 14:25:53|  分类: Struts2 |  标签: |字号大中小 订阅     权限控制是保护系统安全运行很重要 ...

  2. 《深入浅出Windows Phone 8.1 应用开发》基于Runtime框架全新升级版

    <深入浅出Windows Phone 8.1 应用开发>使用WP8.1 Runtime框架最新的API重写了上一本<深入浅出Windows Phone 8应用开发>大部分的的内 ...

  3. 理解Objective C 中id

    什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...

  4. oc是一个全动态语言,oc的一切都是基于runtime实现的!

    oc是一个全动态语言,oc的一切都是基于runtime实现的! 从以下三方面来理解runtime吧! 1. 传统的面向过程的语言开发,例如c语言.实现c语言编译器很简单,只要按照语法规则实现一个LAL ...

  5. KVO的使用三:基于runtime实现KVO

    苹果的KVO原理通过isa-swizzling技术实现,本质实现逻辑是在runtime时添加一个子类,重写set方法进行操作,现在我们也基于runtime来实现一个KVO. 首先新建一个Person类 ...

  6. [iOS]一行代码集成空白页面占位图(基于runtime+MJRefresh思想)

    2018年01月03日阅读 2472   [iOS]一行代码集成空白页面占位图(基于runtime+MJRefresh思想) LYEmptyView 此框架是本人在5,6个月前,公司启动新项目的时候, ...

  7. Spring 框架的概述以及Spring中基于XML的IOC配置

    Spring 框架的概述以及Spring中基于XML的IOC配置 一.简介 Spring的两大核心:IOC(DI)与AOP,IOC是反转控制,DI依赖注入 特点:轻量级.依赖注入.面向切面编程.容器. ...

  8. 【VS开发】【图像处理】基于灰度世界、完美反射、动态阈值等图像自动白平衡算法的原理、实现及效果

    基于灰度世界.完美反射.动态阈值等图像自动白平衡算法的原理.实现及效果      白平衡是电视摄像领域一个非常重要的概念,通过它可以解决色彩还原和色调处理的一系列问题.白平衡是随着电子影像再现色彩真实 ...

  9. WebGIS中基于控制点库进行SHP数据坐标转换的一种查询优化策略

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.前言 目前项目中基于控制点库进行SHP数据的坐标转换,流程大致为:遍 ...

随机推荐

  1. SQL Server读懂语句运行的统计信息 SET STATISTICS TIME IO PROFILE ON

    对于语句的运行,除了执行计划本身,还有一些其他因素要考虑,例如语句的编译时间.执行时间.做了多少次磁盘读等. 如果DBA能够把问题语句单独测试运行,可以在运行前打开下面这三个开关,收集语句运行的统计信 ...

  2. 熟悉css/css3颜色属性

    颜色属性无处不在.字体要用颜色,背景可以有颜色,粒子特效更是离不开颜色.本文参考了一些资料简单总结下以备日后查阅. css中颜色的定义方式: 十六进制色 RGB & RGBA HSL & ...

  3. Java程序-进程中的"进程"

    进程 我们知道程序在磁盘上的时候是静态的,当他被加载到内存的时候,就变成了一个动态的,称为进程,如下图是程序被加载到内存后,在内存中的分布情况如下      此图来自http://blog.csdn. ...

  4. Myeclipse 2015 stable 2.0 完美破解方法

    2015-08-21  以前写了一篇<Myeclipse 2015 stable 1.0 完美破解方法>,现 在跟新一下Myeclipse 2015 stable 2.0 破解方法,此方法 ...

  5. Webmin|Linux管理员远程管理工具

    介绍: Webmin is a web-based interface for system administration for Unix. Using any modern web browser ...

  6. MyBatis学习--SqlMapConfig.xml配置文件

    简介 SqlMapConfig.xml是MyBatis的全局配置文件,在前面的文章中我们可以看出,在SqlMapConfig.xml主要是配置了数据源.事务和映射文件,其实在SqlMapConfig. ...

  7. 在Eclipse中生成接口的JUnit测试类

    在Spring相关应用中,我们经常使用“接口” + “实现类” 的形式,为了方便,使用Eclipse自动生成Junit测试类. 1. 类名-new-Other-java-Junit-Junit Tes ...

  8. ScrollView中嵌套ListView显示

    想要ScrollView中嵌套显示ListView 需要自定义ListView 并重写onMeasure方法 重新计算  heightMeasureSpec的高度 int newHeight = Me ...

  9. 文本溢出省略解决笔记css

    text-overflow:ellipsis; overflow:hidden; white-space:nowrap; *white-space:nowrap;

  10. iOS开发小技巧--实现将图片保存到本地相册

    一.报错的代码 错误 -- out of bounds 超出界限的意思 *** Terminating app due to uncaught exception 'NSInvalidArgument ...