返回

Method Swizzling 探析 Class_addMethod 的初衷

IOS

引言

在苹果官方的开发指南中,Method Swizzling 被定义为一种“黑魔法”的编程手段,意即其本质上具有较高的危险性,稍有不慎便会对应用程序带来难以预料的后果。但另一方面,Method Swizzling 又有着其独特的用武之地,在特定场景下,可以帮助开发者突破既有 API 的束缚,达成特定需求的特殊定制。

本文将带您踏上 Method Swizzling 的探索之旅,从 Method Swizzling 的本质入手,进而解析其底层核心—— class_addMethod,带领您领略这股黑魔法的深层奥义,并最终奉上详细的技术指南,让 Method Swizzling 的运用在您的指尖变得娴熟而富有创造力。

Method Swizzling 浅析

Method Swizzling 的本质在于对既有类中的既有方法进行替换,即时生效。从这个角度来看,Method Swizzling 的确是“黑魔法”无遗,绕过了既有的面向对象的编程惯例,直接触及方法调用的底层细节,打破了类与方法之间的固有联系。

而这一切,都源自于 class_addMethod 这个底层 API 的神奇力量。

class_addMethod 初探

class_addMethod 函数是 Method Swizzling 的基石,它允许开发者向既有类中“硬塞”一个方法。而这个方法,大可以在我们既有的认知体系之外,为既有类带来全新的行为和属性。

class_addMethod 函数的具体语法如下:

IMP class_addMethod(Class cls, SEL name, IMP imp, const char *types)
  • Class cls:要向其内加入方法的类
  • name:方法的 SEL 名称
  • imp:方法的 IMP 指针
  • types:方法的编码字符串

有了这枚黑科技,Method Swizzling 的大门就此洞开。

Method Swizzling 的实战运用

Method Swizzling 的运用场景可谓五花八门,但其核心不外乎“扩展既有类行为”与“修复既有类缺陷”这两大范畴。

场景一:扩展既有类行为

例如,为 NSString 类加入一个 phoneNumberIsValid 方法,方便快速判断字符串中的内容能否构成一组有效的手机号。

#import <objc/message.h>

@interface NSString (PhoneNumber)
- (int)phoneNumberIsValid;
@end

@implentations
- (int)phoneNumberIsValid {
   // 此处填充方法的具体逻辑
}
@end

场景二:修复既有类缺陷

例如,修复 UIWebView 的内存泄漏问题:

#import <objc/message.h>

@interface UIWebView (Leak)
- (void)_uiwebview_dealloc;
@end

@implementations
- (void)_uiwebview_dealloc {
   // 此处填充修复逻辑
}
@end

谨慎运用 Method Swizzling

Method Swizzling 虽好,却需谨慎。由于 Method Swizzling 直接触及方法调用的底层细节,因而极易产生意想不到的副作用。在使用前,务必深思再三,权衡利弊。

结言

Method Swizzling,一个备受争议的编程黑科技,其本质源自 class_addMethod 函数的底层力量。掌握 Method Swizzling 的精髓,便能大幅提升开发的灵活性,补足既有 API 的不足,弥补既有类存在的缺陷。但与之相伴的,是风险与挑战并存。

故而,谨记 Method Swizzling 的双刃剑特性,善加运用,则如虎添翼;反之,则贻害无穷。