最近在使用Swift的过程当中,需要缓存数据,缓存数据的过程中,归档解档是我非常喜欢的一种方式。在OC的通过归档解档缓存模型数据中的数组的时候,有一个归档基类可以实现一键实现自定义对象的归档,虽然通过桥接可以实现OC和Swift的无缝结合,但是还是喜欢单独Swift的基类,所以研究一下运行时,自己写一个归档基类。
iOS开发中的运行时机制是底层的关于C的实现机制,OC代码编译的过程中先转换成C语言的runtime代码,然后汇编运行,OC的底层实现机制大多都是基于运行时的,比如:对象的创建、一个对象属性的内存分配、消息机制、KVC赋值等过程。
Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理。这种动态语言的优势在于:我们写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一个方法的实现等。
这种特性意味着Objective-C不仅需要一个编译器,还需要一个运行时系统来执行编译的代码。对于Objective-C来说,这个运行时系统就像一个操作系统一样:它让所有的工作可以正常的运行。这个运行时系统即Objc Runtime。Objc Runtime其实是一个Runtime库,它基本上是用C和汇编写的,这个库使得C语言有了面向对象的能力。引用1
类的相关操作
类名
- 获取类名:
const char * class_getName ( Class cls );
- 获取父类类型:
Class class_getSuperclass ( Class cls );
- 判断一个类是否是元类(meta class):
BOOL class_isMetaClass ( Class cls );
- 计算一个实例化之后的占用的内存空间:
size_t class_getInstanceSize ( Class cls );
属性
在objc_class中,所有的成员变量、属性的信息是放在链表ivars中的。ivars是一个数组,数组中每个元素是指向Ivar(变量信息)的指针
获取类中指定名称实例成员变量的信息(返回一个指向name属性的Ivar指针):
Ivar class_getInstanceVariable ( Class cls, const char *name );
获取类成员变量的信息(返回的列表不包含父类的成员变量和属性):
Ivar class_getClassVariable ( Class cls, const char *name );
- 添加成员变量:
BOOL class_addIvar ( Class cls, const char *name, size_t size, uint8_t alignment, const char *types );
- 获取整个成员变量列表(返回一个指向成员变量信息的数组,必须使用free()来释放这个数组):
Ivar * class_copyIvarList ( Class cls, unsigned int *outCount );
方法
- 添加方法:
BOOL class_addMethod ( Class cls, SEL name, IMP imp, const char *types );
- 获取实例方法:
Method class_getInstanceMethod ( Class cls, SEL name );
- 获取类方法:
Method class_getClassMethod ( Class cls, SEL name );
- 获取所有方法的数组:
Method * class_copyMethodList ( Class cls, unsigned int *outCount );
替代方法的实现:
IMP class_replaceMethod ( Class cls, SEL name, IMP imp, const char *types );
返回方法的具体实现:
IMP class_getMethodImplementation ( Class cls, SEL name );
IMP class_getMethodImplementation_stret ( Class cls, SEL name );
类实例是否响应指定的selector:
BOOL class_respondsToSelector ( Class cls, SEL sel );
Demo: 操作类的属性和方法
测试类: Person
1 | @interface Person : NSObject |
测试方法:要导入头文件#import <objc/runtime.h>
1 | Person *xm = [[Person alloc] init]; |
运行结果:
1 | 2016-01-26 14:03:28.422 运行时[2683:159792] class name is : Person |