整理一下runtime中class的一些常用API。
Class相关: const char * class_getName(Class cls) Class class_getSuperclass(Class cls) Class class_setSuperclass(Class cls, Class newSuper) 不建议使用的API BOOl class_isMetaClass(Class cls) 判断一个类是不是元类(metaclass) size_t class_getInstanceSize(Class cls) 获得实例变量的Size Ivar class_getInstanceVariable(Class cls, const char * name) 获取成员变量,传入一个c类型的字符串 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) 给类增加一个成员变量,但是这个方法只能用在手动创建一个类的时候,不能用在一个已经存在的类中,也就是说,这个方法要用在objc_allocateClassPair()之后并且在objc_registerClassPair之前。 Ivar * class_copyIvarList(Class cls, unsigned int *outCount) 获取类的成员变量列表,列表的长度为outCount的值,使用这个方法你必须手动去用free()去释放掉。 //Layout???不是很理解,成员变量的约束? const char * class_getIvarLayout(Class cls) void class_setIvarLayout(Class cls, const char *layout) const char *class_getWeakIvarLayout(Class cls) void class_setWeakIvarLayout(Class cls, const char *layout) objc_property_t class_getProperty(Class cls, const char *name) 获取类的属性 objc_property_t * class_copyPropertyList(Class cls, unsigned int *outCount) 获取类的属性数组,同样的也要自己手动去free() BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types) 给类添加一个成员方法,使用这个方法会重写父类已经存在的方法,但不会替换掉该类里面已经存在的方法,如果要替换掉一个成员方法的声明,使用method_setImplementation()来实现。 Method class_getInstanceMethod(Class aClass, SEL aSelector) 获得成员方法。 Method class_getClassMethod(Class aClass, SEL aSelector) 获得类方法,注意该方法会搜索父类的方法声明,使用class_copyMethodList()不会。 Method * class_copyMethodList(Class cls, unsigned int *outCount) 获取类的方法列表(不包括类方法),这种获取方式不会获取父类的方法,如果要获得父类的方法请使用上面两种方式。 IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types) 替换方法,该方法存在以下两种情况: 1.当要替换的方法不存在时,会调用class_addMethod来添加一个新的方法,此时types参数起作用 2.当要替换的方法存在时,替换掉IMP,此时的types参数被忽略 该方法的返回值为替换之前的方法的IMP IMP class_getMethodImplementation(Class cls, SEL name) 获得方法的实现IMP 注意:该方法的效率比method_getImplementation(class_getInstanceMethod(cls, name))高 该函数的返回值并不一定是真正的IMP,因为类的实例对象没有响应该方法时,返回的就不是对应的IMP了。 IMP class_getMethodImplementation_stret(Class cls, SEL name) 该方法返回的是一个struct类型的IMP
上面的API中有些地方值得注意的地方我都在后面写上注释了。
比如class_copyXXXX,要手动去释放free();
比如class_addMethod()这个方法,如果该类的父类中存在这个方法,那么add之后的method会覆盖掉父类的方法。如果在该类中已经存在该方法,你新加的方法也不会起作用,并不会去覆盖掉,具体的大家可以写个demo试一下。