KVO 底层实现的细节
Aapple官方文档中解释道, KVO底层使用了isa-swizling的技术.如果你了解runtime, 那么你应该知道OC中每个对象/类都有isa指针, 一个对象的isa指针指向object's class, 这个object's class对象中有SEL - IMP的dispatch-table.简而言之,isa表示这个对象是哪个类的对象.
当给对象的某个属性注册了一个 observer, 那么这个对象的isa指针指向的class会被改变, 此时系统会创建一个新的中间类(intermediate class)继承原来的class, 然后通过runtime 将原来的isa指针指向这个新的中间类.然后中间类会重写setter方法, 重写的 setter 方法会负责在调用原 setter 方法之前和之后添加willChangeValueForKey:,didChangeValueForKey:两个方法,通知所有观察对象值的更改, 从而触发KVO消息.
block底层实现原理
impl->isa:就是isa指针,可见它就是一个OC对象。
impl->FuncPtr:是一个函数指针,也就是底层将block中要执行的代码封装成了一个函数,然后用这个指针指向那个函数。
Desc->Block_size:block占用的内存大小。
捕获的外部变量:block会捕获外部变量并将其存储在block的底层结构体中。
3种BLOCK
没有访问auto变量的block是NSGlobalBlock类型的,存放在数据段中。
访问了auto变量的block是NSStackBlock类型的,存放在栈中。
NSStackBlock类型的block调用copy成为NSMallocBlock类型并被复制存放在堆中。
runtime-分类为什么不生成setter和getter
https://www.jianshu.com/p/dcc3284b65bf
iOS的分类在runtime实现的结构体中并不存在Ivar类型的容器,缺少了自动合成setter以及getter的必要条件,因此在分类中声明的属性默认为@dynamic修饰。
其次,OC本身是一门原型语言,对象和类原型很像。类对象执行alloc方法就像是原型模式中的copy操作一样,类保存了copy所需的实例信息,这些信息内存信息在runtime加载时就被固定了,没有扩充Ivar的条件。
最后,在runtime中存在一个类型为AssociationHashMap的哈希映射表保存着对象动态添加的属性,每个对象以自身地址为key维护着一个绑定属性表,我们动态添加的属性就都存储在这个表里,这也是动态添加property能成功的基础。
iOS 实现多继承的几种方式
https://www.jianshu.com/p/63104a05d409
1.Son添加两个属性father1(- (void)playFootBall),father2(- (void)playBasketball)。那么Son就有了father1和father2的能力。类似于继承了他们两个!!!
2、delegate和protocol
将C类需要继承的方法以及属性在A和B中各自声明一份协议,C类遵守这两份协议,同时在C类中实现协议中的方法以及属性
3、消息转发(1、快速转发和2、标准转发)
4.类别也可以用来模拟多继承,比如给当前类添加方法,利用runTime来添加属性,方法不表,别人文章
5.NSProxy
与copy相关的面试可能遇到的问题 https://www.jianshu.com/p/48b88ea42f26
讲一讲iOS中的copy和retain
copy创建的新对象也是强引用,在iOS中分为浅拷贝和深拷贝。浅拷贝是指针复制,与源对象指向同一内存地址,源对象的引用计数器会+1。深拷贝是内容拷贝,两个对象内容相同,新的对象 retain 为 1 ,与旧有对象的引用计数无关,旧有对象没有变化。copy 会减少对象对上下文的依赖。
retain 属性表示两个对象地址相同,内容也相同,这个对象的引用计数器+1。
为什么NSString类型的成员变量的修饰属性用copy而不是strong呢?
因为有时候赋给该成员变量的值是NSMutableString类型的,这时候如果修饰符是strong,那成员变量的值就会随着被赋值对象的值的变化而变化。若是用copy修饰,则对NSMutableString类型的值进行了一次深拷贝,成员变量的值就不会随着被赋值对象的值的改变而改变。
对NSMutableString用copy修饰会有什么问题?
答:对NSMutableString用copy修饰得到的是不可变类型NSString对象,如果再对这个对象进行改变会crash。
NSString与NSMutableString的区别主要是:NSMutableString对象所指向内存地址中的内容可以被修改,而NSString对象所指向内存地址中内容不能被修改,但NSString对象不是常量,可以通过为NSString对象重新分配一块内存来改变其指向的内容。
网友评论