基础数据类型
SEL
SEL叫选择器,是表示一个方法的selector的指针,定义如下:
typedef struct objc_selector *SEL;
方法的selector用于表示运行时方法的名字,OC在编译时,会依据每一个方法的名字、参数序列,生成一个唯一的整数标识(Int类型的地址),就是SEL。
SEL sel1 = @selector(method1);
NSLog(@"sel : %p", sel1);
//输出
2014-10-30 18:40:07.518 RuntimeTest[52734:466626] sel : 0x100002d72
两个类之间,不管它们是父类与子类的关系,还是之间没有这种关系,只要方法名相同,那么方法的SEL就是一样的。每一个方法都对应着一个SEL。所以在Objective-C同一个类(及类的继承体系)中,不能存在2个同名的方法,即使参数类型不同也不行。相同的方法只能对应一个SEL。
我们可以在运行时添加新的selector,也可以在运行时获取已存在的selector,我们可以通过下面三种方法来获取SEL:
- sel_registerName函数
- Objective-C编译器提供的@selector()
- NSSelectorFromString()方法
IMP
IMP实际上是一个函数指针,指向方法实现的首地址。其定义如下:
id (*IMP)(id, SEL, ...)
SEL就是为了查找方法的最终实现IMP的。由于每个方法对应唯一的SEL,因此我们可以通过SEL方便快速准确地获得它所对应的IMP,查找过程将在下面讨论。取得IMP后,我们就可以像调用普通的C语言函数一样来使用这个函数指针了。
通过取得IMP,我们可以跳过Runtime的消息传递机制,直接执行IMP指向的函数实现,这样省去了Runtime消息传递过程中所做的一系列查找操作,会比直接向对象发送消息高效一些。
Method
Method用于表示类定义中的方法,则定义如下:
typedef struct objc_method *Method;
struct objc_method {
SEL method_name OBJC2_UNAVAILABLE; // 方法名
char *method_types OBJC2_UNAVAILABLE;
IMP method_imp OBJC2_UNAVAILABLE; // 方法实现
}
struct objc_method_description { SEL name; char *types; };
方法操作API
调用指定方法的实现,返回的是实际实现的返回值。参数receiver不能为空。这个方法的效率会比method_getImplementation和method_getName更快。
id method_invoke ( id receiver, Method m, ... );
调用返回一个数据结构的方法的实现
void method_invoke_stret ( id receiver, Method m, ... );
获取方法名
SEL method_getName ( Method m );
返回方法的实现
IMP method_getImplementation ( Method m );
获取描述方法参数和返回值类型的字符串
const char * method_getTypeEncoding ( Method m );
获取方法的返回值类型的字符串
char * method_getReturnType ( Method m );
获取方法的指定位置参数的类型字符串
char * method_copyArgumentType ( Method m, unsigned int index );
通过引用返回方法的返回值类型字符串
void method_getReturnType ( Method m, char *dst, size_t dst_len );
返回方法的参数个数
unsigned int method_getNumberOfArguments ( Method m );
通过引用返回方法指定位置参数的类型字符串
void method_getArgumentType ( Method m, unsigned int index, char *dst, size_t dst_len );
返回指定方法的方法描述结构体
struct objc_method_description * method_getDescription ( Method m );
设置方法的实现
IMP method_setImplementation ( Method m, IMP imp );
交换两个方法的实现
void method_exchangeImplementations ( Method m1, Method m2 );
返回给定选择器指定的方法的名称
const char * sel_getName ( SEL sel );
在Objective-C Runtime系统中注册一个方法,将方法名映射到一个选择器,并返回这个选择器
SEL sel_registerName ( const char *str );
在Objective-C Runtime系统中注册一个方法
SEL sel_getUid ( const char *str );
比较两个选择器
BOOL sel_isEqual ( SEL lhs, SEL rhs );