OC对象及isa分析

OC对象NSObject在运行时会被转换成:

NSObject *obj = [[NSObject alloc] init];

                ||  转换成

struct NSObject_IMPL {
Class isa;
}

一个NSObject对象在内存中其实是一个结构体,Class是一个指向结构体的指针(void *),32位操作系统下指针占用4个字节,64位下占用8个字节。
所以该结构体在内存中只需要8个字节就够了,但是由于系统分配内存对齐规则(小于16个字节,则分配16字节),所以该NSObject在alloc的时候实际占用16字节。

获取大小方法:

//获得NSObject类实例对象的大小 输出是8
NSLog(@"%zd", class_getInstanceSize([NSObject class]));

//获得obj指针指向的内存区域大小  输出是16
NSLog(@"zd%",malloc_size((__bridge const void *)obj));

自定义对象的研究:
@interface Student : NSObject {
  int _num;
  int _age;
}
@end

在内存中实际会被转换成:

struct Student_IMPL {
  struct NSObject_IMPL NSObject_IVARS;
  int _num;
  int _age;
}

该对象在内存中实际占用16字节,因为NSObject分配了16个字节空间,isa指针只占用8个字节,两个属性各占4个字节,所以系统无需再额外分配空间。

更复杂的继承结构

OC对象分类:
  • instance对象 - 实例对象
  • class对象 - 类对象
  • meta-class - 元类对象
1.实例对象:

通过类alloc出来的

    NSObject *obj = [[NSObject alloc] init];

实例对象在内存中存储的信息包括:

  • isa指针
  • 其他成员变量
2.类对象:

类对象是Class类型指针。
可通过实例对象得到:

    NSObject *obj = [[NSObject alloc] init];
    
    Class objClass1 = [obj class];

或者使用runtime方法:

  NSObject *obj = [[NSObject alloc] init];
    
  Class objClass2 = objcet_getClass(obj);

或者直接调用类方法:

    Class objClass = [NSObject class];

每个类对象在内存中只存在一份,也就是上面的objClass1和objClass2是指向同一块内存。
类对象在内存中存储的信息包括:

  • isa指针
  • superClass指针
  • 类的属性信息(property)。非属性值,因为属性值只存储在实例对象当中,这里存储的是属性类型等
  • 类的对象方法信息(- (void)method)。
  • 类的协议信息(protocol)。
  • 类的成员变量信息(ivar)。
  • 等等...
3.元类对象:

跟类对象一样,也是Class指针类型,所以他们的内存结构是一样的。
只能通过类对象来获得:

    Class objClass = [NSObject class];
    //传入的必须是类对象,如果是实例对象,那么得到的是类对象,而不是元类对象
    Class objMetaClass = object_getClass(objClass);

元类对象在内存中存储的信息包括:

  • isa指针
  • superClass指针
  • 类的方法信息。(+ (void)method)
  • 等等


isa指向:

isa指向

superClass指向:


superClass指向
总结:
  • 实例对象的isa指向类对象
  • 类对象的isa指向元类对象
  • 元类对象的isa指向基类的元类,基类的元类isa指向自身
  • 类对象的superClass指向父类的类对象
  • 基类的类对象的supeClass指向nil
  • 元类对象的supeClass指向父类的元类对象
  • 基类的元类对象的supeClass指向的是基类的类对象

class和meta-class结构

Class类型在内存中实际是objc_class结构体:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • iOS底层原理总结 - 探寻OC对象的本质 对小码哥底层班视频学习的总结与记录。面试题部分,通过对面试题的分析探索...
    xx_cc阅读 22,079评论 31 178
  • 做过iOS开发的同学都应该知道我们平时编写的OC代码的底层实现都是通过C/C++实现的,所以OC的对象都是基于C/...
    小帅798阅读 3,613评论 0 0
  • 写在开始 现在的面试题问的越来越底层,我们也不能一直抱怨说问这些没有用,毕竟底层了解的多一方面能筛选出优秀的开发者...
    coderLZ阅读 2,890评论 1 0
  • Q:觉得自己“最苦最骄傲的一次坚持”是哪次? A:我也希望,自己能比想象中更要强大。但很多时候,坚持下去未必就是好...
    飘雨桐V阅读 2,773评论 0 0
  • 人低自为王, 地低便成海。 大树必招风, 山高易雷鸣。 谦卑皆是福, 狂大自折腰。 善恶终有报, 福祸咎自取。
    老查查阅读 5,040评论 34 66

友情链接更多精彩内容