听名字可能有点不认识,但是介绍下其作用,就会觉得恍然大悟,原来它就叫反射。
0x01 什么是反射
这种动态编程机制,可以让Objective-C
语言更加灵活,说到反射,首先我们需要弄清楚什么是反射:
在运行中程序检查自己和软件运行环境的能力,它可以根据它发现的进行改变。
通俗的讲就是 反射可以在运行时根据类名获得类的信息。
0x01 为什么要用反射
当你要做一个软件可以安装插件的功能,你连插件的类型名称都不知道,怎么示例化这个对象呢?
因为程序是支持插件的(第三方),在开发的时候并不清楚。
所以,无法在代码中new
出来,但反射可以,通过反射,动态加载程序集,然后读出类,检查标记之后再实例化对象,就可以获得正确的类示例。
反射的目的就是为了扩展未知的应用。
iOS中反射及其用处
由于Objective-C
是动态语言,其具备在运行时操作类的方案。
我们可以很方便的通过类名创建指定的类,并且可以通过系统提供的API
获取类中的方法,属性等信息。
通过反射机制,我们可以实现很多有意思的功能,比如:
json->model方案
后台消息确定动态跳转页面
将相似功能的代码抽象组合成更加通用的框架,比如全局跳转,消息中心
0x02 反射怎么用
- 根据字符串/操作获取信息
NSClassFromString // Obtains a class by name.
NSStringFromClass // Returns the name of a class as a string.
NSSelectorFromString // Returns the selector with a given name.
NSStringFromSelector // Returns a string representation of a given selector.
NSStringFromProtocol // Returns the name of a protocol as a string.
NSProtocolFromString // Returns a the protocol with a given name.
- 简单操作
// 根据字符串名获取Class对象
Class clazz = NSClassFromString(@"Car") ;
//直接使用Class来创建对象
id car = [[clazz alloc] init] ;
// 使用performSelector:动态执行方法
[car performSelector:NSSelectorFromString(startEngine)];
- 与运行时一起用功能更加强大
// 获取成员变量列表
Ivar _Nonnull * class_copyIvarList(Class cls, unsigned int *outCount);
// 获取属性列表
objc_property_t _Nonnull * class_copyPropertyList(Class cls, unsigned int *outCount);
// 获取方法列表
Method _Nonnull * class_copyMethodList(Class cls, unsigned int *outCount);
// 还有许多强大的API可以提供操作
0x03 优缺点
优点:
1. 增加程序灵活性,避免将程序写死代码中
2. 代码简洁,提高代码复用率,外部调用方便
3. 对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象都可以调用它任意的方法
缺点:
1. 使用反射,抽象度比较高,不利于代码阅读
2. 对字符串要求比较严格,需要完整对应上,如果代码采用了混淆方案,则难以维护
3. 私有方法可以被访问,破坏封装性
网友评论