一个NSObject 对象占用多少内存
在main.m 中初始化 NSObject 对象 Jump to Definition 可见类的定义
clang -rewrite-objc main.m -o main.cpp
编译一下生成C++文件可见
(IMPL 全称 Implementation 实现)
对比可发现 NSObject对象在内存中就是一个结构体
alloc 相当于分配存储空间给这个结构体
isa是啥 jump进去 发现是objc_class
objc_class 又是啥 继续jump
cache_t cache; 用散列表来缓存调用过的方法,可以提高访问方法的速度
_buckets 是个数组
class_data_bits_t bits; 存储类的方法、属性、遵循的协议等信息的地方
好像跑题了 打住
main.m 中导入头文件
import “objc-runtime.h”
import < malloc/malloc.h >
因为即将使用到两个函数
- class_getInstanceSize(Class cls)
获取NSObject 实例对象的成员变量至少需要的空间大小
Class's ivar size rounded up to a pointer-size boundary.
类的ivar大小四舍五入为指针大小边界。
word_align(unalignedInstanceSize());
这里传入一个未内存对齐的值 然后返回一个做过内存 对齐的值的大小
- malloc_size(const void *ptr);
获取指针对象大小
也就是说 实际给分配了16个字节 但实际上只用来8个
来看一下 alloc 的实现
来看下allocWithZone 的实现
继续 Jump
发现一个创建实例对象方法 继续Jump
这有个初始化函数calloc 传入size 再看size
CF requires all objects be at least 16 bytes
CF要求所有对象至少为16字节
也就是如果小于16全部都设定为16
###综上所述
系统分配了16个字节给NSObject对象
但是只有8个字节被使用
稍微复杂一丢丢的对象
直接上代码
这个虽然一眼就能看出结果,但是为了日后看着方便还是记录一下过程
之前的isa 8位 int 分别占4 位 也就是现在一共 16位 iOS 属于小端 所以读书从高往低读
0x0000001 0x0000002 而不是 0x04 0x05
基础知识 关于大端小端 重温一下
1.大端字节序:高位字节在前,低位字节在后,这是人类读写数值的方法。
2.小端字节序:低位字节在前,高位字节在后,即以0x1122形式储存。
直接找Brother_IMPL 这个实现
包含父类结构体的实现 NSObject_IMPL
Brother 继承自 NSObject NSObject_IMPL结构体中只有一个isa 所以还是8个字节
#更复杂一些有继承关系的
脑补一下clang 之后结构体
NSObject
父类的 8+4 = 12
内存对齐: 结构体大小必须是最大成员大小的倍数 也就是16的倍数 <16 0来补齐define NANO_MAX_SIZE 256 /* Buckets sized {16, 32, 48, 64, 80, 96, 112, ...}
所以16的倍数
子类的
struct Brother_IMPL {
struct Dad_IMPL Dad_IVARS; 16
int _ba; 4
};
16+4 = 20
为啥还是16 因为父类 16其中有4个是空白的
所以直接填充进去了
谨以此做为学习记录之用,如有错误请指出非常感谢
上一篇: 说说XcodeLLDB调试的那些事儿
下一篇: 特别简单的PHP验证码识别