6、面试整理-Runtime面试题整理

248 阅读2分钟

1、OC是动态运行时语言是什么意思?

  • 动态类型:运行时确定对象的类型,编译时期能通过,但不代表运行过程中没有问题
  • 动态绑定:运行时才确定对象调用的方法(消息转发)
  • 动态加载:动态库的方法实现不拷贝到程序中,只记录引用,直到使用相关方法的时候才到库里面查找方法实现

2、runtime能做什么?

  • 获取类的成员变量、方法、协议
  • 为类添加成员变量、方法、协议
  • 动态改变方法实现

3、class_copyIvarListclass_copyPropertyList的区别?

  • 1、class_copyIvarList可以获取.h.m中的所有属性以及@interface大括号中声明的变量,获取的属性名称有下划线(大括号中的除外)。
  • 2、class_copyPropertyList只能获取由@property声明的属性(包括.m),获取的属性名称不带下划线。

4、class_ro_tclass_rw_t的区别?

  • class_rw_t提供了运行时对类拓展的能力,class_rw_t结构体中存储了class_ro_t
  • class_ro_t存储的是类在编译时已经确定的信息,是不可改变的。
  • 二者都存有类的方法、属性(成员变量)、协议等信息,不过存储它们的列表实现方式不同。简单的说class_rw_t存储列表使用的二维数组,class_ro_t使用的一维数组。
  • 运行时修改类的方法,属性,协议等都存储于class_rw_t

5、什么是 Method Swizzle(黑魔法),什么情况下会使用?

  • Method Swizzle 是改变一个已存在的选择器(SEL)对应的实现(IMP)的过程。
  • 类的方法列表存放着SEL的名字和IMP的映射关系。
  • 开发者可以利用 method_exchangeImplementations 来交换2个方法中的IMP
  • 开发者可以利用 method_setImplementation 来直接设置某个方法的IMP
  • 这就可以在运行时改变SELIMP的映射关系,从而实现方法替换。

6、Method Swizzle注意事项

  • 为了确保Swizzle Method方法替换一定被执行调用,可以在load中执行
  • +load里面使用的时候不要调用[super load]。如果多次调用了[super load],可能会出现“Swizzle无效”的假象
  • 避免调用[super load]导致Swizzling多次执行,在load中使用dispatch_once确保交换只被执行一次。
  • 子类替换没有实现的继承方法,会替换掉父类中的实现,影响父类及其他子嘞
  • +initialize 里面使用要加dispatch_once
  • 进行版本迭代的时候需要进行一些检验,防止系统库的函数发生了变化

7、如何hook一个对象的方法,而不影响其它对象?

  • 方法1:新建一个子类重写方法
  • 方法2:让这个对象的类遵循某个协议,hook时判断。弊端是其他对象遵循了这个协议会受到影响。
  • 方法3:运行时创建一个新的子类,修改对象 isa 指针指向子类,hook 时使用isKindOf 判断类型