博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS执行时与method swizzling
阅读量:7086 次
发布时间:2019-06-28

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

      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就能够正常的工作。

转载地址:http://pogml.baihongyu.com/

你可能感兴趣的文章
ajax应用实例 获取各种数据
查看>>
[C++] Returning values by reference in C++
查看>>
匹配图片修改图片名称
查看>>
C#知识点
查看>>
C#之父
查看>>
pytorch加载数据的方法-没弄,打算弄
查看>>
Retrofit进行post提交json数据
查看>>
<base>标签
查看>>
.NET C#读取Excel内容
查看>>
团队-象棋游戏-模块测试过程
查看>>
android之WakeLock机制浅析
查看>>
Springboot连接MySQL8.0出现的问题
查看>>
(转) weblogic 域,管理服务器,受管服务器,集群和机器的基本知识
查看>>
Python之面向对象特性
查看>>
iphone-common-codes-ccteam源代码 CCUIScreen.h
查看>>
CSS 文本和表格中文字溢出显示省略号
查看>>
欧几里得游戏(博弈论启蒙)
查看>>
String 字符串相等比较
查看>>
jsp中九大内置对象
查看>>
Java 文件复制
查看>>