iOS_isa structure

unions and bitfields

Share the same memory space, the one that occupies the largest space in the union

@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;
    }
}

isastructure

isaIt is a union ( union isa_t) <length 8 bytes/64 bits>

  • nonpointer: Indicates whether to isaenable pointer optimization for pointers
    0: pure isa pointer, 1: not only the address of the class object, but isaalso includes class information, reference count of the object, etc.
  • has_assoc: Associated object flag, 0 does not exist, 1 exists
  • has_cxx_dtor: Does the object have C++or Objca destructor, if there is a destructor, you need to do the destructor logic, if not, you can release the object faster
  • shiftcls: Stores the value of the class pointer. With pointer optimization turned on, arm64there is a bit in the schema 33to store the class.newisa.shiftcls = (uintptr_t)cls >> 3
  • magic: Used by the debugger to judge whether the current object is a real object or an uninitialized space
  • weakly_referenced: Whether the flag object is pointed to or once pointed to a ARCweak variable, objects without weak objects can be released faster.
  • deallocating: Whether the flag object is freeing memory
  • has_sidetable_rc: When the object reference count is greater than 10, you need to borrow this variable to store the carry
  • extra_rc: When indicating the reference count value of the object, it is actually the reference count value minus 1, for example, if the reference count of the object is 10, then it extra_rcis 9. If the reference count is greater than 10, you need to use has_sidetable_rcarrival for borrow storage
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;
	

Object< isa> is associated with class< cls>

  • The first property of the object must be isa, since it comes from the parent class
  • Object and class association method < 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
}
  • There can be multiple objects in the current memory, and only one class exists in the current memory
// 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)

kind

class < Class>, metaclass < Meta Class>, root class < Root Class>, root metaclass < Root Meta Class>

  • The first location in the memory of the class points to the metaclass

  • The memory of a class is created by the system. It can be said that a class is a class object created through a metaclass

  • The metaclass is generated by system compilation

  • isaThe < > of the class object object_getClass(obj)obtains the metaclass by means of

  • isaThe < > of the metaclass can object_getClass(obj)get the root class by

  • The < > of the root class isacan object_getClass(obj)get the root metaclass by means of

  • The < > of the root metaclass isacan object_getClass(obj)get the root metaclass by

  • Summary: object isa-> class, class isa-> metaclass, metaclass isa-> root class, root class isa-> root metaclass, root metaclass isa-> root metaclass

isaflow chart

  • The dotted line is isathe flow chart
  • The solid line is the class inheritance relationship
  • NSObjectThe parent class of is nil, and the parent class of the root metaclass isNSObject
    isa flow chart

Guess you like

Origin blog.csdn.net/FlyingKuiKui/article/details/120922838