面向对象
一个 NSObject 对象占用多少内存?
- 系统分配了 16 个字节给 NSObject 对象(通过 malloc_size 函数获得)
- 但 NSObject 对象内部只使用了 8 个字节的空间(64bit 环境下,可以通过 class_getInstanceSize 函数获得)
对象的 isa 指针指向哪里?
- instance 对象的 isa 指向 class 对象
- class 对象的 isa 指向 meta-class 对象
- meta-class 对象的 isa 指向基类的 meta-class 对象
OC 的类信息存放在哪里?
- 对象方法、属性、成员变量、协议信息,存放在 class 对象中
- 类方法,存放在 meta-class 对象中
- 成员变量的具体值,存放在 instance 对象
KVO
iOS 用什么方式实现对一个对象的 KVO?(KVO 的本质是什么?)
- 利用 RuntimeAPI 动态生成一个子类,并且让 instance 对象的 isa 指向这个全新的子类
- 当修改 instance 对象的属性时,会调用 Foundation 的_NSSetXXXValueAndNotify 函数
- willChangeValueForKey:
- 父类原来的 setter
- didChangeValueForKey:
- 内部会触发监听器(Oberser)的监听方法( observeValueForKeyPath:ofObject:change:context:)
如何手动触发 KVO?
- 手动调用 willChangeValueForKey:和 didChangeValueForKey:
直接修改成员变量会触发 KVO 么?
- 不会触发 KVO
通过 KVC 修改属性会触发 KVO 么?
- 会触发 KVO
KVC 的赋值和取值过程是怎样的?原理是什么?
Category 的使用场合是什么?
Category 的实现原理
- Category 编译之后的底层结构是 struct category_t,里面存储着分类的对象方法、类方法、属性、协议信息
- 在程序运行的时候,runtime 会将 Category 的数据,合并到类信息中(类对象、元类对象中)
Category 和 Class Extension 的区别是什么?
- Class Extension 在编译的时候,它的数据就已经包含在类信息中
- Category 是在运行时,才会将数据合并到类信息中
Category 中有 load 方法吗?load 方法是什么时候调用的?load 方法能继承吗?
- 有 load 方法
- load 方法在 runtime 加载类、分类的时候调用
- load 方法可以继承,但是一般情况下不会主动去调用 load 方法,都是让系统自动调用
load、initialize 方法的区别什么?它们在 category 中的调用的顺序?以及出现继承时他们之间的调用过程?
Category 能否添加成员变量?如果可以,如何给 Category 添加成员变量?
- 不能直接给 Category 添加成员变量,但是可以间接实现 Category 有成员变量的效果
block 的原理是怎样的?本质是什么?
- 封装了函数调用以及调用环境的 OC 对象
__block 的作用是什么?有什么使用注意点?
block 的属性修饰词为什么是 copy?使用 block 有哪些使用注意?
- block 一旦没有进行 copy 操作,就不会在堆上
- 使用注意:循环引用问题
block 在修改 NSMutableArray,需不需要添加__block?
我们平时编写的 Objective-C 代码,底层实现其实都是 C\C++代码
graph LR A[Objective-C] --> B[C\C++] --> C[汇编语言] --> D[机器语言]
所以 Objective-C 的面向对象都是基于 C\C++的数据结构实现的
思考:Objective-C 的对象、类主要是基于 C\C++的什么数据结构实现的?
- 结构体
将 Objective-C 代码转换为 C\C++代码
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc OC源文件 -o 输出的CPP文件
- 如果需要链接其他框架,使用-framework 参数。比如-framework UIKit