1、NSArray与NSSet的区别?
NSArray内存中存储地址连续,而NSSet不连续
NSSet效率高,内部使用hash查找;NSArray查找需要遍历
NSSet通过anyObject访问元素,NSArray通过下标访问
2、NSHashTable与NSMapTable?
NSHashTable是NSSet的通用版本,对元素弱引用,可变类型;可以在访问成员时copy
NSMapTable是NSDictionary的通用版本,对元素弱引用,可变类型;可以在访问成员时copy
(注:NSHashTable与NSSet的区别:NSHashTable可以通过option设置元素弱引用/copyin,只有可变类型。但是添加对象的时候NSHashTable耗费时间是NSSet的两倍。
NSMapTable与NSDictionary的区别:同上)
3、属性关键字assign、retain、weak、copy
assign:用于基本数据类型和结构体。如果修饰对象的话,当销毁时,属性值不会自动置nil,可能造成野指针。
weak:对象引用计数为0时,属性值也会自动置nil
retain:强引用类型,ARC下相当于strong,但block不能用retain修饰,因为等同于assign不安全。
strong:强引用类型,修饰block时相当于copy。
4、weak属性如何自动置nil的?
Runtime会对weak属性进行内存布局,构建hash表:以weak属性对象内存地址为key,weak属性值(weak自身地址)为value。当对象引用计数为0 dealloc时,会将weak属性值自动置nil。
5、Block的循环引用、内部修改外部变量、三种block
block强引用self,self强引用block
内部修改外部变量:block不允许修改外部变量的值,这里的外部变量指的是栈中指针的内存地址。__block的作用是只要观察到变量被block使用,就将外部变量在栈中的内存地址放到堆中。
三种block:NSGlobalBlack(全局)、NSStackBlock(栈block)、NSMallocBlock(堆block)
6、KVO底层实现原理?手动触发KVO?swift如何实现KVO?
KVO原理:当观察一个对象时,runtime会动态创建继承自该对象的类,并重写被观察对象的setter方法,重写的setter方法会负责在调用原setter方法前后通知所有观察对象值得更改,最后会把该对象的isa指针指向这个创建的子类,对象就变成子类的实例。
如何手动触发KVO:在setter方法里,手动实现NSObject两个方法:willChangeValueForKey、didChangeValueForKey
swift的kvo:继承自NSObject的类,或者直接willset/didset实现。
7、categroy为什么不能添加属性?怎么实现添加?与Extension的区别?category覆盖原类方法?多个category调用顺序
Runtime初始化时categroy的内存布局已经确定,没有ivar,所以默认不能添加属性。
使用runtime的关联对象,并重写setter和getter方法。
Extenstion编译期创建,可以添加成员变量ivar,一般用作隐藏类的信息。必须要有类的源码才可以添加,如NSString就不能创建Extension。
category方法会在runtime初始化的时候copy到原来前面,调用分类方法的时候直接返回,不再调用原类。如何保持原类也调用(https://www.jianshu.com/p/40e28c9f9da5)。
多个category的调用顺序按照:Build Phases ->Complie Source 中的编译顺序。
8、load方法和initialize方法的异同。——主要说一下执行时间,各自用途,没实现子类的方法会不会调用父类的?
load initialize 调用时机 app启动后,runtime初始化的时候 第一个方法调用前调用 调用顺序 父类->本类->分类 父类->本类(如果有分类直接调用分类,本类不会调用) 没实现子类的方法会不会调用父类的 否 是 是否沿用父类实现 否 是
9、对 runtime 的理解。——主要是方法调用时如何查找缓存,如何找到方法,找不到方法时怎么转发,对象的内存布局
OC中向对象发送消息时,runtime会根据对象的isa指针找到对象所属的类,然后在该类的方法列表和父类的方法列表中寻找方法执行。如果在最顶层父类中没找到方法执行,就会进行消息转发:Method resoution(实现方法)、fast forwarding(转发给其他对象)、normal forwarding(完整消息转发。可以转发给多个对象)
10、runtime 中,SEL和IMP的区别?
每个类对象都有一个方法列表,方法列表存储方法名、方法实现、参数类型,SEL是方法名(编号),IMP指向方法实现的首地址