2019|2019 iOS 面试 -中级篇之 Runtime
1. objc在向一个对象发送消息时,发生了什么?
根据对象的isa指针找到该对象所属的类,去obj的对应的类中找方法
- 1.首先,在相应操作的对象中的缓存方法列表中找调用的方法,如果找到,转向相应实现并执行。
- 2.如果没找到,在相应操作的对象中的方法列表中找调用的方法,如果找到,转向相应实现执行
- 3.如果没找到,去父类指针所指向的对象中执行1,2.
- 4.以此类推,如果一直到根类还没找到,转向拦截调用,走消息转发机制。
- 5.如果没有重写拦截调用的方法,程序报错。
参考:ios objc向一个对象发送消息时,发生了什么?
2. 什么时候会报unrecognized selector错误?iOS有哪些机制来避免走到这一步?
- 对象未实现该方法。
- 对象已经被释放。
- 使用[id respondsToSelector:]进行判断。
参考:什么时候会报unrecognized selector错误?
- 不能向编译后得到的类增加实例变量
- 能向运行时创建的类中添加实例变量
- 1.编译后的类已经注册在runtime中,类结构体中的objc_ivar_list实例变量的链表和instance_size实例变量的内存大小已经确定,runtime会调用class_setvarlayout或class_setWeaklvarLayout来处理strong weak引用.所以不能向存在的类中添加实例变量
- 2.运行时创建的类是可以添加实例变量,调用class_addIvar函数.但是的在调objc_allocateClassPair之后,objc_registerClassPair之前,原因同上.
4. runtime如何实现weak变量的自动置nil? 首先要搞清楚weak属性的特点:
- weak策略表明该属性定义了一种“非拥有关系” (nonowning relationship)。为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。此特质同assign类似;
然而在属性所指的对象遭到摧毁时,属性值也会清空(nil out)
那么runtime如何实现weak变量的自动置nil?
- runtime对注册的类,会进行布局,会将 weak 对象放入一个 hash 表中。用 weak 指向的对象内存地址作为 key,当此对象的引用计数为0的时候会调用对象的 dealloc 方法,假设 weak 指向的对象内存地址是a,那么就会以a为key,在这个 weak hash表中搜索,找到所有以a为key的 weak 对象,从而设置为 nil。
weak属性需要在dealloc中置nil么?
- 在ARC环境无论是强指针还是弱指针都无需在 dealloc 设置为 nil , ARC 会自动帮我们处理,即便是编译器不帮我们做这些,weak也不需要在dealloc中置nil,在属性所指的对象遭到摧毁时,属性值也会清空
- (void)setObject:(NSObject *)object{
objc_setAssociatedObject(self, "object", object, OBJC_ASSOCIATION_ASSIGN);
[object cyl_runAtDealloc:^{
_object = nil;
}];
}
参考链接:runtime 相关试题解答
5. 给类添加一个属性后,在类结构体里哪些元素会发生变化?
- instance_size :实例的内存大小
- objc_ivar_list *ivars:属性列表
相关阅读:
【2019|2019 iOS 面试 -中级篇之 Runtime】1、iOS 面试题 --- 基础部分
2、iOS 面试题 --- 中级篇 Block
3、iOS 面试题 --- 中级篇 Runloop
4、iOS 面试题 --- 高级篇
推荐阅读
- 2019-02-13——今天谈梦想()
- 20190302|20190302 复盘翻盘
- 2019年12月24日
- 2019.4.18感恩日记
- 2020-04-07vue中Axios的封装和API接口的管理
- 2019.4.2咖啡冥想日记
- 2019-1-14
- 亲子日记(287)2019.4.27.
- iOS中的Block
- 考前焦虑——接纳情绪,转移注意力