iOS进阶之底层原理-isa与对象

本文详细探讨了isa指针在对象模型中的角色,解释了其与类的交互,对象结构的组成,以及实例对象、类对象和元类对象的区别。通过源码分析和实例验证,揭示了isa的内部结构和引用计数管理。同时,文章涉及了添加ivar的问题及其在类构造过程中的时机限制。
摘要由CSDN通过智能技术生成

上一篇文章探究了对象的创建已经底层结构,这篇详细介绍isa、对象以及互相的关系。

isa是什么

从源码分析,isa是个共用体,封装了类的信息。

  • nonpointer:是否对isa指针开启指针优化,0为纯isa指针,1:不止对象地址,还包含了类信息、对象引用计数等
  • has_assoc:关联对象标志位
  • has_cxx_dtor: 是否有c++析构函数xin
  • shiftcls:存储类指针的值
  • magic:用于调试器判断当前对象是否是真的对象还是没有初始化的空间
  • weakly_referenced:是否指向或曾经指向弱引用
  • unused: 未使用的
  • has_sidetable_rc: 引用计数表
  • extra_rc:引用计数大于10的时候

isa与类的关系

我们打印了实例对象和类对象的地址,然后通过控制台调试,验证了官网的图。0x0000000ffffffff8ULL为掩码,x/4gx 打印对象,是根据内存偏移,第一个是isa,会在下面的类结构中介绍。

对象的结构

万物皆对象。对象的本质是一个结构体,继承自objc_object(内部包含了isa),包含了superclass、cache、bits,其中cache_t,我们将在下一篇文章单独介绍。

bits内包含了class_rw_t和class_ro_t

class_rw_t结构为,内部包含了方法、属性、协议

method_array_t是一个二维数组

元素为method_t,包含了sel 、types和imp(sel相当于一本书的目录,imp目录所指的页码也就是具体实现)

同理property_array_t也是一样,内部是一个二维数组,含有property_t

protocol_array_t内部含有protocol_t

class_ro_t内部包含i属性、成员变量、协议。

实例对象、类对象、元类对象分别含有什么

这里就直接给出结论了,如果要验证的话,可以通过runtime去验证,大致思路为getIvarList获取成员变量,获取method,判断是否有地址(存在则有)。

  • 实例对象内含有成员变量的具体值
  • 对象方法、属性、成员变量、协议信息,存放在类对象中
  • 类方法,存放在元类对象中

拓展

rw和ro一道面试题,问这样添加会不会有问题。

 Class FFCar = objc_allocateClassPair([NSObject class], "FFCar", 0);
    
//    class_addIvar(FFCar, "brand", sizeof(NSString *), log2(sizeof(NSString *)), "@");
    
    objc_registerClassPair(FFCar);
    
    class_addIvar(FFCar, "brand", sizeof(NSString *), log2(sizeof(NSString *)), "@");
    
    id car = [FFCar alloc];
    [car setValue:@"bgm" forKey:@"brand"];
    FFLog(@"%@",[car valueForKey:@"brand"]);

答案是会崩溃,ivar存在ivars中,存在ro中,所以要在注册类之前就要添加进去。从源码就能看出来,RW_CONSTRUCTING属性是注册类的时候已经确定下来了。

void objc_registerClassPair(Class cls)
{
  
    // Clear "under construction" bit, set "done constructing" bit
    cls->ISA()->changeInfo(RW_CONSTRUCTED, RW_CONSTRUCTING | RW_REALIZING);
    cls->changeInfo(RW_CONSTRUCTED, RW_CONSTRUCTING | RW_REALIZING);

}
BOOL 
class_addIvar(Class cls, const char *name, size_t size, 
              uint8_t alignment, const char *type)
{
    // Can only add ivars to in-construction classes.
    if (!(cls->data()->flags & RW_CONSTRUCTING)) {
        return NO;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值