iOS开发:Runtime面试题合集(二)
1、使用runtime Associate方法关联的对象,需要在主对象dealloc的时候释放么?
无论在MRC下还是ARC下均不需要,被关联的对象在生命周期内要比对象本身释放的晚很多,它们会在被 NSObject -dealloc 调用的object_dispose()方法中释放。
详解:
1、调用 -release :引用计数变为零
对象正在被销毁,生命周期即将结束.
不能再有新的 __weak 弱引用,否则将指向 nil.
调用 [self dealloc]
2、 父类调用 -dealloc
继承关系中最直接继承的父类再调用 -dealloc
如果是 MRC 代码 则会手动释放实例变量们(iVars)
继承关系中每一层的父类 都再调用 -dealloc
>3、NSObject 调 -dealloc
只做一件事:调用 Objective-C runtime 中object_dispose() 方法
>4. 调用 object_dispose()
为 C++ 的实例变量们(iVars)调用 destructors
为 ARC 状态下的 实例变量们(iVars) 调用 -release
解除所有使用 runtime Associate方法关联的对象
解除所有 __weak 引用
调用 free()
2、实例对象的数据结构?
具体可以参看 Runtime
源代码,在文件 objc-private.h
的第 127-232
行。
struct objc_object {
isa_t isa;
//...
}
本质上 objc_object
的私有属性只有一个 isa
指针。指向 类对象
的内存地址。
3、什么是method swizzling(俗称黑魔法)
简单说就是进行方法交换
在Objective-C中调用一个方法,其实是向一个对象发送消息,查找消息的唯一依据是selector的名字。利用Objective-C的动态特性,可以实现在运行时偷换selector对应的方法实现,达到给方法挂钩的目的。 每个类都有一个方法列表,存放着方法的名字和方法实现的映射关系,selector的本质其实就是方法名,IMP有点类似函数指针,指向具体的Method实现,通过selector就可以找到对应的IMP。 换方法的几种实现方式
- 利用 method_exchangeImplementations 交换两个方法的实现
- 利用 class_replaceMethod替换方法的实现
- 利用 method_setImplementation 来直接设置某个方法的IMP
4、什么时候会报unrecognized selector的异常?
objc在向一个对象发送消息时,runtime库会根据对象的isa指针找到该对象实际所属的类,然后在该类中的方法列表以及其父类方法列表中寻找方法运行,如果,在最顶层的父类中依然找不到相应的方法时,会进入消息转发阶段,如果消息三次转发流程仍未实现,则程序在运行时会挂掉并抛出异常unrecognized selector sent to XXX 。
5、何给 Category
添加属性?关联对象以什么形式进行存储?
查看的是 关联对象
的知识点。
详细的说一下 关联对象
。
关联对象
以哈希表的格式,存储在一个全
局的单例中。
@interface NSObject (Extension)
@property (nonatomic,copy ) NSString *name;
@end
@implementation NSObject (Extension)
- (void)setName:(NSString *)name {
objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)name {
return objc_getAssociatedObject(self,@selector(name));
}
@end
6、能否向编译后得到的类中增加实例变量?能否向运行时创建的类中添加实例变量?为什么?
不能向编译后得到的类中增加实例变量;
能向运行时创建的类中添加实例变量;
1.因为编译后的类已经注册在 runtime 中,类结构体中的 objc_ivar_list 实例变量的链表和 instance_size 实例变量的内存大小已经确定,同时runtime会调用 class_setvarlayout 或 class_setWeaklvarLayout 来处理strong weak 引用.所以不能向存在的类中添加实例变量。 2.运行时创建的类是可以添加实例变量,调用class_addIvar函数. 但是的在调用 objc_allocateClassPair 之后,objc_registerClassPair 之前,原因同上.
7、类对象的数据结构?
具体可以参看 Runtime
源代码。
类对象就是
objc_class
。
struct objc_class : objc_object {
// Class ISA;
Class superclass; //父类指针
cache_t cache; // formerly cache pointer and vtable 方法缓存
class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags 用于获取地址
class_rw_t *data() {
return bits.data(); // &FAST_DATA_MASK 获取地址值
}
它的结构相对丰富一些。继承自objc_object
结构体,所以包含isa
指针
isa
:指向元类superClass
: 指向父类Cache
: 方法的缓存列表data
: 顾名思义,就是数据。是一个被封装好的class_rw_t
。
转载自:https://juejin.cn/post/6844904090129039374