SwizzleMethod 黑魔法

Bug制造机
• 阅读 4487

首先,请加入runtime头文件 #import <objc/runtime.h>

    void swizzleMethod(Class class, SEL originalSelector, SEL swizzledSelector)
    {
        // the method might not exist in the class, but in its superclass
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
        
        // class_addMethod will fail if original method already exists
        BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
        
        // the method doesn’t exist and we just added one
        if (didAddMethod) {
            class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
        }
        else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    }

上面这个C风格函数,就是SwizzleMethod的核心方法,用来交换Runtime中类和对象的方法接口指针。但是这有什么用呢?

你知道有名的第三方库IQKeyboard么?

这个吊库,不需要引入头文件,不需要调用任何方法就能使用。怎么做到的呢?
答案是NSObject的 + (void)load方法。

这个类方法,在软件运行时一定会调用一次,并且不需要调用super方法,因为父类的load方法也一定会调用。

IQKeyboard就是在load方法中初始化的。

SwizzleMethod应用实例 —— 无痛手术

这个比喻并不准确,准确说应该是无痕手术 —— 对方法的无痕手术
首先给AppDelegate添加Category,可以放在新文件中哦,比如AppDelegate+Extension.h & m。

+ (void)load
{
    swizzleMethod([AppDelegate class], @selector(application:didFinishLaunchingWithOptions:), @selector(swizzle_application:didFinishLaunchingWithOptions:));
}

这里,我们把AppDelegate的启动方法更换成了我们自己的swizzle_application:didFinishLaunchingWithOptions方法。两个方法指针互换,然后我们在我们的方法中加入我们需要的代码。

- (BOOL)swizzle_application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //我们需要添加的代码
    //
    return [self swizzle_application:application didFinishLaunchingWithOptions:launchOptions];
}

注意到了么,结尾我们自己调用swizzle_application:application方法,因为这个这个方法指针实际已经指向AppDelegateapplication:didFinishLaunchingWithOptions方法。其他地方掉用AppDelegateapplication:didFinishLaunchingWithOptions方法则会指向我们的swizzle_application:application方法,这样我们就在人不知不觉中,向AppDelegate插入了一段代码,这一切不需要AppDelegate引入任何头文件,是不是很Cool?

这样一来就可以把需要放在这里面的各种监测代码初始化,都放到我们的swizzle_application:application方法中,可以给这个方法新建一个类,每次新建工程直接拖进来一起编译,分分钟植入,帅爆一切,点个赞吧。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Runtime 隐藏Status Bar背景
这次的主题的 Runtime ,对于很多人来说,习惯了面向对象的编程语言之后再接触C语言一开始是拒绝的。但是当你真的用起来了,你会上瘾,因为这彻彻底底地满足了极客们的折腾心理,用代码操控一切的心理。就拿我做大象公会的例子来说(对了,这是我在Smartisan的第一个项目,也是独立开发的一款App),你知道Smartisan一贯的软件设
Stella981 Stella981
3年前
PhoneGap设置Icon
参考:http://cordova.apache.org/docs/en/latest/config\_ref/images.html通过config.xml中的<icon标签来设置Icon<iconsrc"res/ios/icon.png"platform"ios"width"57"height"57"densi
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
可莉 可莉
3年前
10分钟教你用Python爬取Baidu文库全格式内容
!(https://oscimg.oschina.net/oscnet/fe00aeba4aa8e2873e2a4a18a4066315c38.jpg)程序猿声代码黑科技的分享区!(https://oscimg.oschina.net/oscnet/de84f57eed4cea63681fd0aaf5b5b95fb44.g
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这