Runtime常用API
class相关API
objc_allocateClassPai |
创建一个新类和元类 |
objc_disposeClassPair |
销毁一个类及其关联的元类 |
objc_registerClassPair |
注册使用分配的类(注册前添加成员变量) |
class_getName |
返回类的名称 |
class_getSuperclass |
返回一个类的父类 |
class_isMetaClass |
返回一个布尔值,该值表示类对象是否为元类 |
class_getInstanceSize |
返回类实例的大小 |
class_addIvar |
向类添加新的实例变量 |
class_copyIvarList |
描述类声明的实例变量列表 |
class_getProperty |
返回具有给定类的给定名称的属性 |
class_copyPropertyList |
描述类声明的属性列表 |
class_addMethod |
向具有给定名称和实现的类添加新方法 |
class_getInstanceMethod |
返回给定类的指定实例方法 |
class_getClassMethod |
返回一个指向给定类的给定类方法的数据结构的指针 |
class_copyMethodList |
描述类实现的实例方法列表 |
class_replaceMethod |
替换给定类的方法的实现 |
class_getMethodImplementation |
如果将特定消息发送到类的实例,则返回将被调用的函数指针 |
class_respondsToSelector |
返回一个布尔值,该值指示类的实例是否响应特定选择器 |
class_copyProtocolList |
描述类所采用的协议 |
class_addProperty |
向类添加属性 |
class_getVersion |
返回类定义的版本号 |
class_setVersion |
设置类定义的版本号 |
class_conformsToProtocol |
返回一个布尔值,指示一个类是否符合给定的协议 |
object相关API
object_copy |
返回给定对象的副本(ARC不可用) |
object_dispose |
释放给定对象占用的内存(ARC不可用) |
object_setInstanceVariable |
更改类实例的实例变量的值(ARC不可用) |
object_getInstanceVariable |
获取类实例的实例变量的值(ARC不可用) |
object_getIvar |
读取对象中实例变量的值(不可以访问值类型) |
object_setIvar |
设置对象中实例变量的值 |
object_getClassName |
返回给定对象的类名 |
object_getClass |
返回对象的类 |
object_setClass |
设置对象的类 |
获取类定义
objc_getClassList |
获取已注册的类定义列表 |
objc_copyClassList |
创建并返回指向所有已注册类定义的指针列表 |
objc_getClass |
返回指定类的类定义 |
objc_getMetaClass |
返回指定类的元类定义 |
使用实例变量
ivar_getName |
返回实例变量的名称 |
ivar_getTypeEncoding |
返回实例变量的类型字符串 |
关联对象
objc_setAssociatedObject |
使用给定的键和关联策略为给定对象设置关联值 |
objc_getAssociatedObject |
返回与给定键的给定对象关联的值 |
objc_removeAssociatedObjects |
删除给定对象的所有关联 |
发送消息
objc_msgSend |
向类的实例发送带有简单返回值的消息 |
objc_msgSendSuper |
向类实例的父类发送带有简单返回值的消息 |
method相关API
method_invoke |
调用指定方法的实现 |
method_invoke_stret |
调用返回数据结构的指定方法的实现 |
method_getName |
返回方法的名称 |
method_getImplementation |
返回方法的实现 |
method_getTypeEncoding |
返回描述方法参数和返回类型的字符串 |
method_copyReturnType |
返回描述方法返回类型的字符串 |
method_copyArgumentType |
返回描述方法的单个参数类型的字符串 |
method_getReturnType |
通过引用返回描述方法返回类型的字符串 |
method_getNumberOfArguments |
返回方法接受的参数数量 |
method_getArgumentType |
通过引用返回描述方法的单个参数类型的字符串 |
method_getDescription |
返回指定方法的方法描述结构 |
method_setImplementation |
设置方法的实现 |
method_exchangeImplementations |
交换两种方法的实现 |
sel相关API
sel_getName |
返回由给定选择器指定的方法的名称 |
sel_registerName |
向运行时系统注册一个方法,将方法名称映射到选择器,并返回选择器值 |
sel_isEqual |
返回一个布尔值,指示两个选择器是否相等 |
协议相关API
objc_getProtocol |
返回指定的协议 |
objc_copyProtocolList |
返回运行时已知的所有协议的数组 |
objc_allocateProtocol |
创建一个新的协议实例 |
objc_registerProtocol |
向运行时注册新创建的协议 |
protocol_addMethodDescription |
向协议添加方法 |
protocol_addProtocol |
将已注册的协议添加到正在构建的另一个协议中 |
protocol_addProperty |
向正在构建的协议添加属性 |
protocol_getName |
返回协议的名称 |
protocol_isEqual |
返回一个布尔值,指示两个协议是否相等 |
protocol_copyPropertyList |
返回由协议声明的属性数组 |
protocol_getProperty |
返回给定协议的指定属性 |
protocol_copyProtocolList |
返回协议采用的协议数组 |
protocol_conformsToProtocol |
返回一个布尔值,指示一个协议是否符合另一个协议 |
属性相关
property_getName |
返回属性的名称 |
property_getAttributes |
返回属性的属性字符串 |
property_copyAttributeValue |
返回给定属性名称的属性属性的值 |
property_copyAttributeList |
返回给定属性的属性属性数组 |
常用API的使用示例
- 动态创建类并添加成员变量和方法
void test1(void) { Class personCls = objc_allocateClassPair([NSObject class], "Person", 0);//创建类 class_addIvar(personCls, "name", sizeof(NSString *), 0, "@"); //添加成员变量 IMP runImp = imp_implementationWithBlock(^(id p1, id p2){ NSLog(@"run - %@ - %@", p1, p2);// run - <Person: 0x100621420> - lisi });//添加方法实现 class_addMethod(personCls, sel_registerName("run:"), runImp, nil); //添加方法 objc_registerClassPair(personCls); //注册类 id person = [personCls new]; //初始化类 [person setValue:@"zs" forKey:@"name"]; //给成员变量赋值 objc_msgSend(person, sel_registerName("run:"), @"lisi"); //调用run:方法 NSLog(@"%@", [person valueForKey:@"name"]); //打印结果: zs NSLog(@"%@", object_getClass(person));//打印结果: Person } • 类中的成员变量的常用操作 @interface Student : NSObject @property(strong, nonatomic) NSString *hobby; @property(assign, nonatomic) NSInteger age; @end @implementation Student @end void test2(void) { //获取实例变量的值 Student *stu = [Student new]; stu.hobby = @"hobby - value"; Ivar ivar = class_getInstanceVariable([stu class], "_hobby"); //获取ivar id name = object_getIvar(stu, ivar); //获取成员变量的值 NSLog(@"%@", name); //打印结果: hobby - value object_setIvar(stu, ivar, @"set - value"); //给成员变量赋值 id name2 = object_getIvar(stu, ivar); //获取成员变量的值 NSLog(@"%@", name2); //打印结果: set - value unsigned int count = 0; Ivar *ivars = class_copyIvarList([stu class], &count); //获取ivar list for (int i = 0; i < count; i++) { Ivar var = ivars[i]; const char *name = ivar_getName(var); //取出成员变量的名称 NSLog(@"所有成员变量: %@", [NSString stringWithCString:name encoding:NSUTF8StringEncoding]); }//打印结果:所有成员变量: _hobby;所有成员变量: _age }
- 整合上面两段代码
将person的isa指向了Student,以后访问person的时候,相当于直接访问student
void test3(void) { object_setClass(person, [stu class]); NSLog(@"%@", [person valueForKey:@"_hobby"]); //打印结果: zs }
- 实例方法的方法交换
@interface Student : NSObject - (void)studentTest; @end @implementation Student - (void)studentTest { NSLog(@"studentTest"); } @end @interface Student (Cate) @end @implementation Student (Cate) + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ //hook实例方法传入类对象 [self hookMethod:[self class] originSelector:@selector(studentTest) swizzledSelector:@selector(hook_studentTest)]; }); } + (void)hookMethod:(Class)cls originSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector { Method originalMethod = class_getInstanceMethod(cls, originalSelector);//获取当前类的Method Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector);//获取当前类的hook Method //向当前类中增加方法,并将实现指向当前类中的原始方法,防止调用[self hook_xxx]的时候找不到方法 //意味着调用当前类中的hook_xxx方法的时候,相当于调用当前类的原始方法 //添加不存在的方法此处返回YES BOOL didAddMethod = class_addMethod(cls, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); if (didAddMethod) { //意味着调用当前中的原始方法的时候,相当于调用当前类的hook_xxx方法 class_replaceMethod(cls, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else {//交换imp方法实现 method_exchangeImplementations(originalMethod, swizzledMethod); } } - (void)hook_studentTest { NSLog(@"hook - studentTest"); [self hook_studentTest]; } @end void test4(void) { Student *stu = [Student new]; [stu studentTest]; } int main(int argc, const char * argv[]) { @autoreleasepool { test4(); } return 0; }
打印结果:
hook - studentTest studentTest
调用studentTest前先调用了hook - studentTest
- 类方法的方法交换
@interface Student : NSObject + (void)classMethod; @end @implementation Student + (void)classMethod { NSLog(@"classMethod"); } @end @interface Student (Cate) @end @implementation Student (Cate) + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ //object_getClass([self class]) - 改动 //实例方法向类对象里面查找,类方法向元类方法里面查找,故此处应该传入元类对象 [self hookMethod:object_getClass([self class]) originSelector:@selector(classMethod) swizzledSelector:@selector(hook_classMethod)]; }); } + (void)hookMethod:(Class)cls originSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector { Method originalMethod = class_getClassMethod(cls, originalSelector);//获取当前类的Method - 改动 Method swizzledMethod = class_getClassMethod(cls, swizzledSelector);//获取当前类的hook Method - 改动 //向当前类中增加方法,并将实现指向当前类中的原始方法,防止调用[self hook_xxx]的时候找不到方法 //意味着调用当前类中的hook_xxx方法的时候,相当于调用当前类的原始方法 //添加不存在的方法此处返回YES BOOL didAddMethod = class_addMethod(cls, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); if (didAddMethod) { //意味着调用当前中的原始方法的时候,相当于调用当前类的hook_xxx方法 class_replaceMethod(cls, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else {//交换imp方法实现 method_exchangeImplementations(originalMethod, swizzledMethod); } } + (void)hook_classMethod { NSLog(@"hook_classMethod"); [self hook_classMethod]; } @end void test6(void) { [Student classMethod]; } int main(int argc, const char * argv[]) { @autoreleasepool { test6(); } return 0; }
打印结果:
hook_classMethod classMethod
- 代理方法的方法交换
@protocol MyDelegate <NSObject> - (void)delegateMethod; @end @interface Student : NSObject @property(weak, nonatomic) id <MyDelegate> delegate; - (void)callMethod; @end @implementation Student - (void)callMethod { if ([self.delegate respondsToSelector:@selector(delegateMethod)]) { [self.delegate delegateMethod]; } } @end @interface Student (Cate) @end @implementation Student (Cate) + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ [self hookMethod:[self class] originSelector:@selector(setDelegate:) swizzledSelector:@selector(hook_setDelegate:)]; }); } + (void)hookMethod:(Class)cls originSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector { Method originalMethod = class_getInstanceMethod(cls, originalSelector);//获取当前类的Method Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector);//获取当前类的hook Method //向当前类中增加方法,并将实现指向当前类中的原始方法,防止调用[self hook_xxx]的时候找不到方法 //意味着调用当前类中的hook_xxx方法的时候,相当于调用当前类的原始方法 //添加不存在的方法此处返回YES BOOL didAddMethod = class_addMethod(cls, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); if (didAddMethod) { //意味着调用当前中的原始方法的时候,相当于调用当前类的hook_xxx方法 class_replaceMethod(cls, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else {//交换imp方法实现 method_exchangeImplementations(originalMethod, swizzledMethod); } } - (void)hookMethod:(Class)cls originSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector { Method originalMethod = class_getInstanceMethod(cls, originalSelector);//获取代理类的Method Method swizzledMethod = class_getInstanceMethod([self class], swizzledSelector);//获取当前类的hook Method //向代理类中增加方法,并将实现指向代理类中的原始方法,防止调用[self hook_xxx]的时候找不到方法 //意味着调用代理类中的hook_xxx方法的时候,相当于调用代理类的原始方法 //添加不存在的方法此处返回YES BOOL didAddMethod = class_addMethod(cls, swizzledSelector, class_getMethodImplementation(cls, originalSelector), method_getTypeEncoding(originalMethod)); if (didAddMethod) {//替换代理类中的原始方法的实现为当前类中的hook_xxx方法 //意味着调用代理中的原始方法的时候,相当于调用当前类的hook_xxx方法 class_replaceMethod(cls, originalSelector, class_getMethodImplementation([self class], swizzledSelector), method_getTypeEncoding(swizzledMethod)); }else { NSLog(@"来到此处说明交换的方法已经在原类中实现了,需要更换一下hook的方法名称"); } } - (void)hook_setDelegate:(id<MyDelegate>)delegate { [self hookMethod:[delegate class] originSelector:@selector(delegateMethod) swizzledSelector:@selector(hook_delegateMethod)]; [self hook_setDelegate:delegate]; } - (void)hook_delegateMethod { NSLog(@"hook_delegateMethod"); [self hook_delegateMethod]; } @end @interface MyClass : NSObject<MyDelegate> @end @implementation MyClass - (void)delegateMethod { NSLog(@"MyClass - delegateMethod"); } @end void test5(void) { Student *stu = [Student new]; MyClass *myClass = [MyClass new]; stu.delegate = myClass; [stu callMethod]; } int main(int argc, const char * argv[]) { @autoreleasepool { test5(); } return 0; }
打印结果:
hook_delegateMethod MyClass - delegateMethod
本文部分内容来可能来源于网络,发布的内容如果侵犯了您的权益,请联系我们尽快删除!