iOS执行时与method swizzling
C语言是静态语言,它的工作方式是通过函数调用,这样在编译时我们就已经确定程序怎样执行的。而Objective-C是动态语言,它并不是通过调用类的方法来执行功能,而是给对象发送消息,对象在接收到消息之后会去找匹配的方法来执行。这样的做法就把C语言在编译时的工作挪到了执行时来做,能够获得额外的灵活性。
在Objective-C中有个@selector,在非常多地方被翻译成“选择子”。实际上,对于类的实例对象来说,类的方法是用一个数字来代表的,并不是是我们看到的一个长长的带着:这个字符的一串字符串。通过这个@selector就能够把这种方法的名字转成所相应的数字。当一个类确定后,实际上每一个方法的@selector的值就是固定的,讲到这里,你一定能够想到method swizzling是什么一个东东了,没错,假设我们原来有个A方法,@selector(A)就是一个数字,我们的对象在接收到一个消息后就去查找相应的方法并执行——假设,我们把@selector(B)的数字换成了原来@selector(A)的数字,那么此时对象尽管受到A消息,但会去执行B方法!
在iOS中,这是全然能够实现的,那么我们什么时候会须要这么做呢?我认为有2个时候:
1. 破解,毋庸讳言,这绝对是破解的利器,不解释了。
2. 在开发调试过程中,假设你对某个库里的方法不确定或者认为须要扩展的时候,你能够自己写一个去取代它。由于Objective-C是有Category的,所以扩展功能没啥必要,但调试时添加�一些打印语句是非常方便实际的。
举个样例,NSString里面的lowercaseString方法,假设我不太清楚这种方法都干了什么,我就能够自己写个方法来替换它,这种方法里面添加�打印语句,这样log里面就一目了然了。
首先须要添加�一个NSString的Category
@interface NSString (wzTest) - (NSString*)myLowerString; @end @implementation NSString (wzTest) - (NSString*)myLowerString
{
NSString *lowerString = [self myLowerString];
NSLog(@"%@ => %@", self, lowerString);
return lowerString;
} @end
这里有一个地方解释一下,在myLowerString方法里面,看起来递归调用了自身。可是,我们会用原来的lowercaseString方法去替换自己写的myLowerString方法,所以这里并没有调用自身,而是调用了原来的lowercaseString方法。这点请注意一下。
其次替换系统原来的lowercaseString方法,使用runtime里面的方法。
Method originalMethod = class_getInstanceMethod([NSString class], @selector(lowercaseString));
Method swapMethod = class_getInstanceMethod([NSString class], @selector(myLowerString));
method_exchangeImplementations(originalMethod, swapMethod);
NSString *testStr = @"thIs is THE Test STRING";
NSLog(@"lowerString of testStr=%@", [testStr lowercaseString]);
我们来看一下log的结果:
2014-05-29 22:17:55.514 testTableView[1582:a0b] thIs is THE Test STRING => this is the test string
2014-05-29 22:17:55.514 testTableView[1582:a0b] lowerString of testStr=this is the test string
我们能够看到,系统中使用是继续使用lowercaseString方法的,只是实际运行的是我们新增的方法。当你不须要这样做的时候,关闭method swizzling方法就能够恢复了。
我们的样例中是添加�了打印语句,实际上还能够做很多其它地操作。这在用第三方库调试的时候是非常实用的一个方法,能够非常方便的查看变量的内容或做一些其它工作。调试结束后,关闭method swizzling就能够正常的工作。
iOS执行时与method swizzling的更多相关文章
- iOS运行时与method swizzling
C语言是静态语言,它的工作方式是通过函数调用,这样在编译时我们就已经确定程序如何运行的.而Objective-C是动态语言,它并非通过调用类的方 法来执行功能,而是给对象发送消息,对象在接收到消息之后 ...
- 【原】iOS动态性(三) Method Swizzling以及AOP编程:在运行时进行代码注入
概述 今天我们主要讨论iOS runtime中的一种黑色技术,称为Method Swizzling.字面上理解Method Swizzling可能比较晦涩难懂,毕竟不是中文,不过你可以理解为“移花接木 ...
- IOS 开发之 Method Swizzling + Category
ios 分类中如果增加的方法与被扩展的类方法名重复,则原方法就没法被调用….看以下例子 例如: @interface ClassA : NSObject - (NSString *) myMethod ...
- IOS 开发之 Method Swizzling
ios 分类中如果增加的方法与被扩展的类方法名重复,则原方法就没法被调用….看以下例子 例如: @interface ClassA : NSObject - (NSString *) myMethod ...
- Method Swizzling
学习博客: http://www.cocoachina.com/ios/20160121/15076.html (这个作者太牛了,写了我一直想知道的类簇的swizz方法) 一. 一般的swizz 先给 ...
- iOS中AOP与Method Swizzling 项目中的应用
引子:项目中需要对按钮点击事件进行统计分析,现在项目中就是在按钮的响应代码中添加点击事件,非常繁琐.所以使用了AOP(面向切面编程),将统计的业务逻辑统一抽离出来. 项目中添加的开源库:https:/ ...
- ios逆向工程-内部钩子(Method Swizzling)
Method Swizzling(方法调配) 怎么说呢,先了解什么是钩子为什么用钩子,学过C++的朋友应该清楚,hook就是用来获得(截断/改变)底层调用的方法.这样我们可以自由的修改或者读取一些想要 ...
- ios method swizzling
阅读器 iOS开发iOS 本文由TracyYih[博客]翻译自NSHipster的文章Method Swizzling. 在上周associated objects一文中,我们开始探索Ob ...
- iOS 使用Method Swizzling隐藏Status Bar
在iOS 6中,隐藏Status Bar很的简单. // iOS 6及曾经,隐藏状态栏 [[UIApplication sharedApplication] setStatusBarHidden:YE ...
随机推荐
- 一切皆为 JavaScript
JavaScript起源于Netscape公司的LiveScript语言,这是一种基于对象和事件驱动的client脚本语言.最初的设计是为了检验HTML表单输入的正确性. 早些年,JavaScript ...
- pc机进入android的shell
一直都知道自己非常死板,刚刚再一次验证了.. 下载下来android开发必备的工具之后,就按部就班的一步步的来了.没想过这些工具有没有其它用处,更有甚者,在刚開始接触android的时候.居然不知道自 ...
- hdu2159 Fate 二维背包
#include <cstring> #include <string> #include <cstdio> #include <cmath> #inc ...
- DMA过程分析
1.1 当我们在应用程序中编写write系统调用,向磁盘中写入数据时,写入请求会先调用底层写函数,将请求先写入内存中的页快速缓存(page cache)中,写入成功则立马返回,真正的写入磁盘操作会延迟 ...
- iOS视图控制器之间delegate传值教程
之前在StackOverFlow上看到一篇讲传值(segue传值和delegate传值)的文章,感觉讲的非常清晰,就将delegate部分翻译了一下.有兴趣能够看看. 原文: http://stack ...
- 类型自动转换引起的误解——QString可以赋值数字1,也能直接与0比较,真是昏倒!
看以下代码,能编译通过: void MainWindow::on_pushButton_clicked() { QString str = "test"; ) { QMessage ...
- nginx 区分pc和mobile 到不同的404页面
if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry|vivo)') { set $mobile_request '1'; } ...
- phpStorm打开提示 failed to create JVM 的解决的方法
phpStorm 软件打开执行提示 failed to create JVM的解决的方法. 改动文件 D:\Program Files (x86)\JetBrains\PhpStorm 7.1.3\b ...
- [cocos2d-x][apk打包][Fatal signal 11][andriod]Eclipse编译Fatal signal 11报错-都是字符赋值惹的祸
流程重现: 使用coco2d-x制作了一个2048,在xcode模拟器执行以及在pad上真机调试都是没有问题的. 可是在使用eclipse调试打包android可以执行,可是进入游戏之后会在随机的地方 ...
- 基于DSP的疲劳驾驶检测系统的研究
原地址:http://www.chinaaet.com/article/index.aspx?id=114534 关键词:疲劳检测DSP亮瞳效应PERCLOS 摘 要: 针对汽车驾驶员疲劳驾驶检测的 ...