当前位置:   article > 正文

method-swizzling 详解 和使用_swizzle 算法详解

swizzle 算法详解

简介

在Objective-C中调用一个方法,其实是向一个对象发送消息,查找消息的唯一依据是selector的名字。利用Objective-C的动态特性,可以实现在运行时偷换selector对应的方法实现。
每个类都有一个方法列表,存放着selector的名字和方法实现的映射关系。IMP有点类似函数指针,指向具体的Method实现。
我们可以利用 method_exchangeImplementations 来交换2个方法中的IMP,
我们可以利用 class_replaceMethod 来修改类,
我们可以利用 method_setImplementation 来直接设置某个方法的IMP,
通过上边的方法,可以把类的调度表(dispatch table)中选择器到最终函数间的映射关系 替换。就相当于把IMP 的只想替换了。

  • swizzling 需要在 + (void)load{}中使用
  • swizzling 需要保证只执行一次。 需要使用 dispatch_once;
  • load 和initialize区别:load是只要类所在文件被引用就会被调用,而initialize是在类或者其子类的第一个方法被调用前调用。所以如果类没有被引用进项目,就不会有load调用;但即使类文件被引用进来,但是没有使用,那么initialize也不会被调用。

使用场景 (1)

需要统计事件,或者需要输出Log的时候,可以使用。比如在delloc中,输出log。告诉我们哪个类释放了。

+ (void)swizzWithClass:(Class)class originSel:(SEL)originSel newSel:(SEL)newSel{

Method originM = class_getInstanceMethod(class, originSel);
Method newM = class_getInstanceMethod(class, newSel);

IMP newImp =  method_getImplementation(newM);

BOOL addMethodSucess = class_addMethod(class, newSel, newImp, method_getTypeEncoding(newM));

if (addMethodSucess) {
    class_replaceMethod(class, originSel, newImp, method_getTypeEncoding(newM));
}else{
    method_ex
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号