Runtime之基础知识

仅仅是一个速查方法,也算是看了半天头文件翻译出来的东西吧。

先了解几个关键字

  • class:类
  • metaClass :元类
  • instance: 实例变量
  • ivars:成员变量
  • property:属性
  • method:方法
  • SEL:选择子
  • IMP:方法的具体实现

Class-类相关的操作函数

这方面的操作可以使用NSObject的相关类方法得到相同的结果。

1
2
3
4
5
6
7
8
//获取类名:
const char * class_getName ( Class cls );

//获取类的父类:
Class class_getSuperclass ( Class cls );

//判断指定的类是不是一个元类:
BOOL class_isMetaClass ( Class cls );

Instance-实例变量的操作函数

1
2
//获取实例变量大小:
size_t class_getInstanceSize ( Class cls );

在objc_class中,所有的成员变量、属性的信息是放在链表ivars中的。ivars是一个数组,数组中每个元素是指向Ivar(变量信息)的指针。

Ivar-成员变量的操作函数

1
2
3
4
5
6
7
8
//获取类中指定名称的成员变量信息:
Ivar class_getInstanceVariable ( Class cls, const char *name );

//获取类成员变量的信息:
Ivar class_getClassVariable ( Class cls, const char *name );

//获取整个成员变量列表:
Ivar * class_copyIvarList ( Class cls, unsigned int *outCount );

Property-属性相关的函数操作

1
2
3
4
5
6
7
8
9
10
11
//获取指定的属性:
objc_property_t class_getProperty ( Class cls, const char *name );

//获取属性列表:
objc_property_t * class_copyPropertyList ( Class cls, unsigned int *outCount );

// 为类添加属性
BOOL class_addProperty ( Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount );

//替换类的属性:
void class_replaceProperty ( Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount );

Method-方法相关的函数

方法就是选择子(SEL)和方法实现(IMP)组成的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 添加方法
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 );

协议的相关操作函数

1
2
3
4
5
6
7
8
// 添加协议
BOOL class_addProtocol ( Class cls, Protocol *protocol );

// 返回类是否实现指定的协议
BOOL class_conformsToProtocol ( Class cls, Protocol *protocol );

// 返回类实现的协议列表
Protocol * class_copyProtocolList ( Class cls, unsigned int *outCount );

runtime的强大之处在于它能在运行时创建类和对象

动态创建类

动态创建类涉及到以下几个函数:

1
2
3
4
5
6
7
8
// 创建一个新类和元类
Class objc_allocateClassPair ( Class superclass, const char *name, size_t extraBytes );

// 销毁一个类及其相关联的类
void objc_disposeClassPair ( Class cls );

// 在应用中注册由objc_allocateClassPair创建的类
void objc_registerClassPair ( Class cls );

objc_allocateClassPair函数:如果我们要创建一个根类,则superclass指定为Nil。extraBytes通常指定为0,该参数是分配给类和元类对象尾部的索引ivars的字节数。

为了创建一个新类,我们需要调用objc_allocateClassPair。然后使用诸如class_addMethod,class_addIvar等函数来为新创建的类添加方法、实例变量和属性等。完成这些后,我们需要调用objc_registerClassPair函数来注册类,之后这个新类就可以在程序中使用了。

实例方法和实例变量应该添加到类自身上,而类方法应该添加到类的元类上。

动态创建对象

动态创建对象的函数如下:

1
2
3
4
5
6
7
8
// 创建类实例
id class_createInstance ( Class cls, size_t extraBytes );

// 在指定位置创建类实例
id objc_constructInstance ( Class cls, void *bytes );

// 销毁类实例
void * objc_destructInstance ( id obj );

class_createInstance函数:创建实例时,会在默认的内存区域为类分配内存。extraBytes参数表示分配的额外字节数。这些额外的字节可用于存储在类定义中所定义的实例变量之外的实例变量。该函数在ARC环境下无法使用。

objc_constructInstance函数:在指定的位置(bytes)创建类实例。

objc_destructInstance函数:销毁一个类的实例,但不会释放并移除任何与其相关的引用。