面试题答案
一键面试Method Swizzling基本实现原理
- Runtime机制基础:Objective-C是基于runtime运行时机制的语言。在runtime中,对象接收到消息时,runtime会在对象所属类的方法列表中查找对应的方法实现。每个类都有一个方法列表(
method list
),方法以Method
结构体的形式存在,Method
结构体包含了方法名、方法实现等信息。 - 交换方法实现:Method Swizzling的核心是通过runtime提供的函数,将两个方法的实现进行交换。通常使用
class_getInstanceMethod
函数获取类的实例方法,method_exchangeImplementations
函数来交换两个方法的实现。例如,我们想交换viewDidLoad
和一个自定义方法swizzled_viewDidLoad
的实现,首先获取这两个方法,然后调用method_exchangeImplementations
函数交换它们的实现。这样,当原本调用viewDidLoad
方法时,实际上会执行swizzled_viewDidLoad
的代码,反之亦然。
使用Method Swizzling潜在问题
- 线程安全问题:Method Swizzling操作不是线程安全的。如果在多线程环境下同时进行Method Swizzling操作,可能会导致程序崩溃。因为多个线程同时修改类的方法列表可能会造成数据竞争和不一致。
- 影响范围不可控:一旦进行了Method Swizzling,它会影响到该类及其所有子类的所有实例。如果不小心在某个基础类上进行了Swizzling,可能会对整个继承体系产生意想不到的影响,使得问题排查变得困难。
- 与系统方法冲突:如果交换的方法是系统类的方法,当系统更新后,系统方法的实现可能发生变化,这可能导致Swizzling后的代码出现兼容性问题。
- 调试困难:由于Method Swizzling改变了方法的实际执行逻辑,在调试时可能会出现难以理解的行为。原本期望调用的方法实际执行的是另一个方法的代码,这增加了调试的难度,特别是在大型项目中。