博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
动态添加方法的代码分析
阅读量:4697 次
发布时间:2019-06-09

本文共 1784 字,大约阅读时间需要 5 分钟。

动态添加方法的代码分析

之前自己写代码时只是单纯的使用method_exchangeImplementations来进行方法的相互替换,但是偶然间看到别人写的方法替换,发现很不错,很严谨, 代码如下:

+ (void)load{    static dispatch_once_t token;    dispatch_once(&token, ^{        Class class = [self class];        SEL originalSelector = @selector(viewWillAppear:);        SEL swizzledSelector = @selector(skx_viewWillAppear:);        Method originalMethod = class_getInstanceMethod(class, originalSelector);        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);        BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));        if (success) {            class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));        } else {            method_exchangeImplementations(originalMethod, swizzledMethod);        }    });}

初看方法,第一感觉比较困惑的是为什么在load方法中还要进行dispatch_once. 对此的解释是:虽然load方法只执行一次, 但是说不准某些人会显示调用呢. 所以为了稳妥, 还是加个dispatch_once.

method_exchangeImplementations 这个方法就不介绍了,主要作用是交换两个方法的IMP.

主要看这里:

BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));if (success) {            class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));}

首先进行的第一步是addMethod. why? 而且还是拿的原始的selector去进行方法的添加. 但是我们所需要的不正是对原始selector对应的IMP的替换吗? 为什么会有success这个判断呢?

答案只有一个, 那就是此类中其实不存在此方法.这个方法是从父类继承而来的.这时就需要先判断一下:如果方法实际是从父类继承而来的, 那么addMethod就会返回true, 进而再去进行方法的替换.

在此方法是从父类继承而来的情况下, 方法的method_exchangeImplementations还是可以成功的,子类正常使用还是没问题的. 但是如果父类调用了这个被替换的方法, 那么就会崩溃. 因为方法的添加替换都是在子类中进行的, 父类找不到这个方法.

综上, 别人写的代码还是很严谨啊, 还要多学习.

转载于:https://www.cnblogs.com/shaox/p/5146785.html

你可能感兴趣的文章
Error和Exception
查看>>
Python和Singleton (单件)模式[转载]
查看>>
httpclient设置proxy与proxyselector
查看>>
IT常用单词
查看>>
拓扑排序
查看>>
NYOJ--32--SEARCH--组合数
查看>>
JMS
查看>>
gulpfile 压缩模板
查看>>
【34.14%】【BZOJ 3110】 [Zjoi2013]K大数查询
查看>>
【 henuacm2016级暑期训练-动态规划专题 A 】Cards
查看>>
第五篇:白话tornado源码之褪去模板的外衣
查看>>
设备常用框架framework
查看>>
bootstrap模态框和select2合用时input无法获取焦点(转)
查看>>
MockObject
查看>>
Chukwa
查看>>
(转)Maven仓库——私服介绍
查看>>
设计模式之工厂模式
查看>>
仿复制粘贴功能,长按弹出tips的实现
查看>>
Kubernetes-Host网络模式应用
查看>>
第三次作业
查看>>