ios-动态添加方法,交换方法,重定向方法

mac2022-06-30  83

  新建一个类Person,Person.h 不写代码,Person.m 有如下两个方法:

- (void)eat { NSLog(@"xxx eat===="); }

【动态添加方法】

  尝试在 Person 类里添加一个 run 的实例方法。加上如下两个方法即可:

void run(id self, SEL sel, NSString *str) { NSLog(@"xxx run==%@", str); } // 只要调用了该类未实现的方法,就会来到这个方法 + (BOOL)resolveInstanceMethod:(SEL)sel { BOOL isSucess = NO; if (sel == @selector(run:)) { isSucess = class_addMethod(self, sel, run, "v@:@"); } return isSucess; }

  然后调用运行和打印如下:

Person *p = [Person new]; [p performSelector:@selector(run:) withObject:@"222xxxxxxxxxxx"]; // log: xxx run==222xxxxxxxxxxx

  在 ios调用私有方法 中有提到如何打印一个类下的方法 ,这里调用测试如下

[self getMethods]; Person *p = [Person new]; [p performSelector:@selector(run:) withObject:@"222xxxxxxxxxxx"]; [self getMethods];

  打印如下:

=============0 方法名= eat 参数类型= @ 参数类型= : 返回类型值类型= v xxx run==222xxxxxxxxxxx =============0 方法名= run: 参数类型= @ 参数类型= : 参数类型= @ 返回类型值类型= v =============1 方法名= eat 参数类型= @ 参数类型= : 返回类型值类型= v

  从上面这个打印也可以看出,当没有调用这个方法时,打印 Person 类下方法只有eat一个;当调用了 run 方法后,这个方法就被添加到 Person 类的 methodlist 里了。

【交换方法】

  在 Person.m 中加一个 -sleep 方法

- (void)eat { NSLog(@"xxx eat===="); } - (void)sleep { NSLog(@"xxx sleep==="); }

  可以在 Person 的 + load 方法中进行方法交换,因为一个类的 +load 方法在该类载入内存时就会开始调用。

+ (void)load { Method m1 = class_getInstanceMethod(self, @selector(sleep)); Method m2 = class_getInstanceMethod(self, @selector(eat)); method_exchangeImplementations(m1, m2); }

  调用 run: 方法和打印如下: (从打印可以发现,方法已经被替换了)

  Person *p = [Person new];

   [p performSelector:@selector(sleep)]; // log: xxx eat====

   [p performSelector:@selector(eat)];  // log: xxx sleep===

【重定向方法】

  在 Person.m 中 + load 方法如下: (意思是将sleep方法编号定向到eat方法的实现中)

+ (void)load { Method m1 = class_getInstanceMethod(self, @selector(sleep)); IMP imp = class_getMethodImplementation(self, @selector(eat)); method_setImplementation(m1, imp); }

  调用打印如下:(可以看到最终两个方法都进入eat)

Person *p = [Person new]; [p performSelector:@selector(sleep)]; // log: xxx eat==== [p performSelector:@selector(eat)]; // log: xxx eat====

 

转载于:https://www.cnblogs.com/buerjj/p/8546209.html

最新回复(0)