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

时间: 2024-10-12 17:58:42

iOS执行时与method swizzling的相关文章

iOS运行时与method swizzling

C语言是静态语言,它的工作方式是通过函数调用,这样在编译时我们就已经确定程序如何运行的.而Objective-C是动态语言,它并非通过调用类的方法来执行功能,而是给对象发送消息,对象在接收到消息之后会去找匹配的方法来运行.这种做法就把C语言在编译时的工作挪到了运行时来做,可以获得额外的灵活性. 在Objective-C中有个@selector,在很多地方被翻译成"选择子".实际上,对于类的实例对象来说,类的方法是用一个数字来代表的,并非是我们看到的一个长长的带着:这个字符的一串字符串.

iOS开发之 Method Swizzling 深入浅出

<p align="center"><img src ="https://raw.githubusercontent.com/DotzuX/Notes/master/logo.jpeg"/></p> iOS开发之 Method Swizzling 深入浅出 只要善用Google,网上有很多关于Method Swizzling的Demo,在这里我就不打算贴代码了,主要介绍下概念,原理,注意事项等等. 开发需求 如果产品经理突然说:&

iOS 开发:Method Swizzling

iOS 开发之Method Swizzling 前言 如果你还不知道什么是Method Swizzling,你可以看看NSHipster 的文章 ,我简单介绍一下,method swizzling 可以看成劫持了一个方法. 我们可以看看NSHipster 的文章中有以下代码: - (void)xxx_viewWillAppear:(BOOL)animated { [self xxx_viewWillAppear:animated]; NSLog(@"viewWillAppear: %@"

iOS黑魔法-Method Swizzling

公司年底要在新年前发一个版本,最近一直很忙,好久没有更新博客了.正好现在新版本开发的差不多了,抽空总结一下.由于最近开发新版本,就避免不了在开发和调试过程中引起崩溃,以及诱发一些之前的bug导致的崩溃.而且项目比较大也很不好排查,正好想起之前研究过的Method Swizzling,考虑是否能用这个苹果的“黑魔法”解决问题,当然用好这个黑魔法并不局限于解决这些问题...... 需求 就拿我们公司项目来说吧,我们公司是做导航的,而且项目规模比较大,各个控制器功能都已经实现.突然有一天老大过来,说我

iOS黑魔法之Method Swizzling

此黑魔法本应属于OC,它是基于Runtime实现的偷天换日大法. 那么什么是Method Swizzling呢?从字面意思来看叫方法协调,大概就是这个意思了.使用此魔法可以替换现有方法为自定义方法,来个偷天换日,偷梁换柱. 使用方法很简单,代码基本为以下框架.但其具有较强的魔力,这是一个方法hook啊. /** * Method Swizzling * 黑魔法之偷天换日 */ #import "UIViewController+Extension.h" #import <objc

iOS 使用Method Swizzling隐藏Status Bar

在iOS 6中,隐藏Status Bar非常的简单. // iOS 6及以前,隐藏状态栏 [[UIApplication sharedApplication] setStatusBarHidden:YES]; 来到了iOS 7的年代以后,需要在UIViewController中指定: #ifdef __IPHONE_7_0 - (BOOL)prefersStatusBarHidden { return YES; } #endif 并通过下列代码刷新状态栏: if ([viewController

ios method swizzling

阅读器 iOS开发iOS 本文由TracyYih[博客]翻译自NSHipster的文章Method Swizzling. 在上周associated objects一文中,我们开始探索Objective-C运行时的一些黑魔法.本周我们继续前行,来讨论可能是最受争议的运行时技术:method swizzling. Method swizzling指的是改变一个已存在的选择器对应的实现的过程,它依赖于Objectvie-C中方法的调用能够在运行时进改变——通过改变类的调度表(dispatch tab

ios逆向工程-内部钩子(Method Swizzling)

Method Swizzling(方法调配) 怎么说呢,先了解什么是钩子为什么用钩子,学过C++的朋友应该清楚,hook就是用来获得(截断/改变)底层调用的方法.这样我们可以自由的修改或者读取一些想要的东西.(个人理解) 下面是百度百科的解释:钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的.当消息到达后,在目标窗口处理函数之前处理它.钩子机制允许应用程序截获处理window消息或特定事件 那io

iOS runtime探究(四): 从runtiem开始实践Category添加属性与黑魔法method swizzling

你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639335 本文主要讲解runtime相关知识,从原理到实践,由于包含内容过多分为以下五篇文章详细讲解,可自行选择需要了解的方向: 从runtime开始: 理解面向对象的类到面向过程的结构体 从runtime开始: 深入理解OC消息转发机制 从runtime开始: 理解OC的属性property 从runtime开始: 实践Category添加属