iOS_isa结构

联合体与位域

共用同一内存空间,联合体内占用空间最大的那个

@interface Trnk : NSObject
@property (nonatomic, assign) BOOL front;
@property (nonatomic, assign) BOOL back;
@property (nonatomic, assign) BOOL left;
@property (nonatomic, assign) BOOL right;
@end
#define DirectionFrontMask    (1 << 0)
#define DirectionBackMask     (1 << 1)
#define DirectionLeftMask     (1 << 2)
#define DirectionRightMask    (1 << 3)

@interface Tank () {
    
    
    // 联合体
    union{
    
    
        char bits;
        // 位域
        strcut {
    
    
            char front : 1;
            char back  : 1;
            char left  : 1;
            char right : 1;
        };
    } _direction;
}
@end
@implementation LGTank

- (instancetype)init
{
    
    
    self = [super init];
    if (self) {
    
    
        _direction.bits = 0b0000000000;
    }
    return self;
}

- (void)setFront:(BOOL)isFront {
    
    
    if (isFront) {
    
    
        _direction.bits |= DirectionFrontMask;
    } else {
    
    
        _direction.bits &= ~DirectionFrontMask;
    }
}

isa结构

isa就是一个联合体(union isa_t)<长度8字节/64位>

  • nonpointer:标识是否对isa指针开启指针优化
    0:纯isa指针,1:不止是类对象地址,isa中包含了类信息、对象的引用计数等
  • has_assoc:关联对象标志位,0没有,1存在
  • has_cxx_dtor:该对象是否有C++ 或者Objc的析构器,如果有析构函数,则需要做析构逻辑,如果没有,则可以更快的释放对象
  • shiftcls:存储类指针的值。开启指针优化的情况下,在arm64架构中有33位用来存储类。 newisa.shiftcls = (uintptr_t)cls >> 3
  • magic:用于调试器判断当前对象是真的对象还是没有初始化的空间
  • weakly_referenced:标志对象是否被指向或者曾经指向一个ARC的弱变量,没有弱对象的对象可以更快释放。
  • deallocating:标志对象是否正在释放内存
  • has_sidetable_rc:当对象引用计数大于10时,则需要借用该变量存储进位
  • extra_rc:当表示该对象的引用计数值,实际上是引用计数值减1,例如,如果对象的引用计数为10,那么extra_rc为9。如果引用计数大于10,则需要使用到has_sidetable_rc来进行借位存储
union isa_t {
    
    
	isa_t() {
    
    }
	isa_t(uintptr_t value) : bits(value) {
    
    }
	Class cls;
	uintptr_t bits;
#if define(ISA_BITFIELD)
	struct {
    
    
		ISA_BITFIELD;
	}
#endif
}
//  arm64架构下  ISA_BITFIELD
	uintptr_t  nonpointer				:1;
	uintptr_t  has_assoc				:1;
	uintptr_t  has_cxx_dtor				:1;
	uintptr_t  shiftcls					:33;
	uintptr_t  magic					:6;
	uintptr_t  weakly_referenced		:1;
	uintptr_t  deallocating				:1;
	uintptr_t  has_sidetable_rc			:1;
	uintptr_t  extra_rc					:19;
	

对象<isa >与类<cls>关联

  • 对象的第一个属性必然是isa,由于其来自于父类
  • 对象与类关联方式<isa.bits & ISA_MASK = Class>
// 以下对象<obj>均为非TaggedPointer对象,且存在

// 根据对象获取类
Class object_getClass (id obj) {
    
    
	if (obj) return obj->getIsa();
	else return Nil;
}

objc_object::getIsa() {
    
    
	if (!isTaggedPointer())  return ISA();
	
	uintptr_t ptr = (uintptr_t)this;
	if (isTaggedPointer()) {
    
    
		// 省略...
	} else {
    
    
	  	// 省略...
	}
}

objc_object::ISA() {
    
    
	assert(!isTaggedPointer());
#if SUPPORT_INDEXED_ISA
	if (isa.nonpointer) {
    
    
		uintptr_t slot = isa.indexcls;
		return classForIndex((unsigned)slot);
	}
	return (Class)isa.bits;
#else
	return (Class)(isa.bits & ISA_MASK)
#endif
}
  • 对象当前内存中可以有多个,类在当前内存中只存在一份
// class1~4结果一致,则可以证明类只存在一份
Class class1 = [Person class];
Class class2 = [Person alloc].class;
Class class3 = [Person alloc].class;
Class class4 = object_getClass([Person alloc]);
NSLog(@"\n%p-\n%p-\n%p-\n%p",class1,class2,class3,class4)

类<Class>、元类<Meta Class>、根类<Root Class>、根元类<Root Meta Class>

  • 类的内存第一个位置指向元类

  • 类的内存是由系统创建,可以说类是通过元类进行创建的类对象

  • 元类是由系统编译生成的

  • 类对象的<isa>通过object_getClass(obj)的方式获取到元类

  • 元类的<isa>可以通过object_getClass(obj)的方式获取到根类

  • 根类的<isa>可以通过object_getClass(obj)的方式获取到根元类

  • 根元类的<isa>可以通过object_getClass(obj)的方式获取到根元类

  • 总结:对象isa -> 类、类isa -> 元类、元类isa ->根类、根类isa->根元类 、根元isa-> 根元类

isa流程图

  • 虚线为isa流程图
  • 实线为类继承关系
  • NSObject 的父类为nil,根元类的父类是NSObject
    isa流程图

猜你喜欢

转载自blog.csdn.net/FlyingKuiKui/article/details/120922838
isa