iOS 基础概念1 OC对象的本质 NSObject @interface NSObject { Class isa ; } @end isa struct NSObject_IMPL { Class isa; }; Class isa; 等价于 struct objc_class *isa; 8字节 NSObject对象的底层就是一个包含了一个指针的结构体,它的大小最小8字节 64位系统讨论 内存大小 class_getInstanceSize 获取一个objc类的实例的实际占用大小,部分属性没有值肯定就没有占用内存了 malloc_size 对象实际分配的空间,内存对齐原则,iOS都是16字节的整数倍 占用8字节的,实际分配16字节,多余8字节用不上。 如果实际占用40字节的, 实际分配内存16*3 = 48 sizeof() 计算对象结构定义上可能需要的大小,单纯定义类型大小的累加,编译时计算。 假如对象没有初始化,那实际占用大小0,但是sizeof可不管 源码定义 :#define NANO_MAX_SIZE 256 /* Buckets sized {16, 32, 48, 64, 80, 96, 112, ...} NANO最大分配256字节,是源码库里面的其中一种内存分配方法,类似的还有 frozen、legacy、magazine、purgeable 对象种类 instance对象(实例对象) 类对象通过alloc方法创建 包含:isa指针,其他成员变量 class对象(类对象) 用来描述一个instance对象 内部存放 isa指针 superclass指针 类的属性信息(@property) 对象方法信息(instance method) 协议信息(protocol) 成员变量信息(ivar) 一个类的类对象是唯一的,在内存中只存一份 meta-class对象 (元类对象) 作用:用来描述一个class对象 内部存放 isa指针 superclass指针 类方法信息(+ class方法) 元类对象在内存中也是只有一份的 实际也是class生成,只是比类对象少用一些字段 cls 结构 class结构- 旧版 struct objc_class { Class _Nonnull isa OBJC_ISA_AVAILABILITY; #if !__OBJC2__ Class _Nullable super_class OBJC2_UNAVAILABLE; const char * _Nonnull name OBJC2_UNAVAILABLE; long version OBJC2_UNAVAILABLE; long info OBJC2_UNAVAILABLE; long instance_size OBJC2_UNAVAILABLE; struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE; struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE; struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE; struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE; #endif } OBJC2_UNAVAILABLE; class 结构 - 新版 struct objc_class : objc_object { // objc_object 内包含 isa // Class ISA; Class superclass; cache_t cache; // 缓存表 class_data_bits_t bits; // class_rw_t内部用来获取基础信息的标记 class_rw_t *data() { // 方法,属性,协议 ,对象信息 等都整合到此处 return bits.data(); } //下面是一大堆的方法 ... ... ... } 方法对比 object_getClass Class object_getClass(id obj) { if (obj) return obj->getIsa(); else return Nil; } 此方法返回对象的isa指针 传入instance对象,返回对应的class对象 传入class对象,返回对应的meta-class对象 传入meta-class对象,返回NSObject(基类)的meta-class对象 - (Class)class [obl class] 返回对应的类对象class + (Class)class [cls class] 返回类对象本身 对象方法查找 本段流程是忽略缓存的情况(第一次查找且没有缓存过),下文会有cache_t 篇 详细解释完整流程 instance 对象 调用当前对象方法 通过isa到对应类对象,在类对象找到对象方法,一般先看缓存 调用父类对象方法 1.通过isa到对应类对象 2.通过类对象supperclass指针 找到父类的类对象,然后在其找对象方法, 找不 到会一层层往上遍历,直到基类 class 类对象 调用当前类的类方法 通过isa找到对应的元类对象,在元类对象找类方法,一般先看缓存 调用父类的类方法 1.通过isa找到对应的元类对象 2.通过元类对象supperclass指针 找到父类的元类对象,然后在其找类方法, 找 不到会一层层往上遍历,直到根类 同样也会先查找缓存,没有的下次会缓存起来 信息存放 1.对象方法,属性信息,成员变量信息,协议信息,存放在class对象中 2.类方法,存放在meta-class对象中 3. 成员变量的具体值,存放在instance对象中