Comment on page
08 一套iOS底层试卷
- A: 4
- [X] B: 8
- C: 16
- D: 64
- [X] A:成员变量
- [X] B: supClass
- [X] C: cache_t
- [X] D: bit
A
struct Struct1 {
char b;// 1
int c; // 4
double a; // 8
short d; // 2
}struct1;
struct Struct2 {
double a;
int b;
char c;
short d;
}struct2;
struct Struct3 {
double a;
int b;
char c;
struct Struct1 str1;
short d;
int e;
struct Struct2 str2;
}struct3;
- A: 48
- [X] B: 56
- C: 64
- D: 72
C
BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
BOOL re3 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]];
BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];
NSLog(@" re1 :%hhd\n re2 :%hhd\n re3 :%hhd\n re4 :%hhd\n",re1,re2,re3,re4);
BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];
BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];
BOOL re7 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]];
BOOL re8 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]];
NSLog(@" re5 :%hhd\n re6 :%hhd\n re7 :%hhd\n re8 :%hhd\n",re5,re6,re7,re8);
- A: 1011 1111
- B: 1100 1011
- [X] C: 1000 1111
- D: 1101 1111
- A: 7
- [X] B: 8
- C: 14
- D: 16
union kc_t {
uintptr_t bits;// 8
struct {
int a;// 4
char b;// 1
};
}
- [X] A: 8
- B: 12
- C: 13
- D: 16
- A: 自己 , 根元类
- [B] B: 自己 , NSObject
- C: 根元类 , 根元类
- [X] D: 根元类 , NSObject
- A: 哈希函数原因 , 不解决
- [X] B: 哈希函数原因 , 再哈希
- C: 他存他的我也布吉岛 , 再哈希
- D: 他乱由他乱,清风过山岗 , 不解决
- [X] A: 先从缓存快速查找
- [X] B: 慢速递归查找methodlist (自己的和父类的,直到父类为nil)
- [X] C: 动态方法决议
- [X] D: 消息转发流程
- A: 类方法存在元类(以对象方法形式存在), 元类的父类最终是 NSObject 所以我们可以通过resolveInstanceMethod 防止 NSObject 中实现了对象方法!
- B: 因为在oc的底层最终还是对象方法存在
- [X] C: 类方法存在元类以对象方法形式存在.
- D: 咸吃萝卜,淡操心! 苹果瞎写的 不用管
A
- 对
- [X] 错
- [X] 对
- 错
- [X] 对
- 错
- [X] 对
- 错
- 对
- [X] 错
对
- [X] 对
- 错
xcrun 或 clang
debug - DebugWorkflow - Always show disassembly
- 查看汇编可以从更深层次了解当前函数的汇编层面的执行,为
OBJC
源码分析提供信息,部分源码的执行被LLDB进行了改动,结合会变查看可以避免方向性错误,结合memory read
可以更清楚的看到寄存器之间是如何让互相配合处理配合的。使用汇编查看流程可以再不确定源码出处和执行流程的情况下,跟踪内部代码,并找到出处。同时,结合符号断点的方式能够更清楚的跟踪源码实现。
- 从首地址开始,1️以8字节的形式打印4段地址
- 打印地址
- 取出
$0
地址中的数据
- 实例方法保存在类 的方法列表中
- 类方法保存在元类的方法列表中
- 这样设计的好处:
- 底层不用区分类方法和对象方法,本质上都是对象方法。方法调用都可以理解为消息发送,只不过消息的接收者不一样。
- 这样设计更加的面向对象,类的一切信息都存储在元类中,对象的一切信息都存储在类中。类是元类实例化出的对象,实例对象是类实例化出的对象。存储也更符合面向对象的特点。
- OC语言早期借鉴了另一种
SmallTalk
的语言,其中也是这么设计的。
ISA包含在
ISA_BITFIELD
中, & ISA_MASK
是为了去除ISA地址两边的数据(标志位
、引用计数
等),拿到正确的ISA地址。- class_ro_t
- read only
- 类名、方法、协议、成员变量等
- Clean memory
- 运行时不会改变
- class_rw_t
- read write
- 使用来读写数据的,在这个数据结构中存储了只有在运行时才会生成的信息。
- 可读可写
- Dirty memory
- 运行时会改变
- class_rw_ext_t
- read write extension
- 动态添加的
- 方法
- 属性
- 协议等
- 这将 class_rw_t 的体积减少了进 50%。在有需要的时候将 class_rw_ext_t 插入其中,约 90% 的类用不到这些拓展数据
Dirty memory 要比 Clean memory 昂贵的多,只要进程在运行,他就一直存在。Clean memory 可以进行移除,以节省空间;如果需要可以再从磁盘中加载。之所以将Class的数据分成两部分,是为了尽可能的节省空间
- 一般情况
- 3/4
- 真机Arm64
- 7/8
- 小缓 存特殊情况
- 100%
- 为什么
- 效率
效率高
ISA
Last modified 2yr ago