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 ...
随机推荐
- GitHub上项目配置和导入eclispe的问题解决
在github上下载的工程文件导入的时候总是遇到各种各样的问题,昨天晚上瞎忙一晚上查资料没搞定.早上找高手请教了一下,一起弄了好一会终于解决了,这里记录一下方法解决的具体方法步骤. 本方法适用于离线导 ...
- MySQL字符集编码
MySQL字符集编码总结 之前内部博客上凯哥分享了一篇关于mysql字符集的文章,之前我对mysql字符集一块基本没有深究过,看到凯哥文章后有些地方有点疑惑,遂自己去看了mysql的官方文档,并參考了 ...
- 百度搜索结果页url参数详解
在百度首页输入任意关键词搜索之后,我们跳转到搜索结果页面,在浏览器的网址栏我们可以看到很长的一串url地址.那么,你真的了解这一串url的含义吗? s?:搜索 百度搜索结果页使用了重定向,因此我们看到 ...
- sqlserver 存储过程学习笔记(二) 在项目中的应用<多表分页>
(1)存储过程建立 USE [NewPlat] GO /****** Object: StoredProcedure [dbo].[usp_PagingLarge] Script Date: ...
- __NSAutoreleaseNoPool(): ... utoreleased with no pool in place - just leaking
__NSAutoreleaseNoPool(): ... utoreleased with no pool in place - just leaking 我的平台 mac os 10.6 Xcode ...
- 奔小康赚大钱 hdu 2255
奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- Lambda高手之路第一部分
转http://www.cnblogs.com/lazycoding/archive/2013/01/06/2847574.html 介绍 Lambda表达式是使代码更加动态,易于扩展并且更加快速(看 ...
- 开源搜索引擎评估:lucene sphinx elasticsearch
开源搜索引擎评估:lucene sphinx elasticsearch 开源搜索引擎程序有3大类 lucene系,java开发,包括solr和elasticsearch sphinx,c++开发,简 ...
- JavaFX2: 鼠标拖动选择和Ctrl+Shift连续区间选择的ListView
JavaFX2的ListView中的多选没有提供鼠标拖动选择的功能,同时按下Ctrl和Shift后连续的区间选中也不支持,以下代码用于处理这两个问题,细节见代码注释: import com.sun.j ...
- Android内存管理
首先Android理机制相当复杂.想要讲清楚比較困难.其次对于绝大多数用户来说.仅仅关心内存够不够用,至于内存怎样管理的这样的技术细节,不是用户须要去考虑的,写这样一个专题有没有意义?毕竟我们是用手机 ...