Article directory
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;
}
}
isa
structure
isa
It is a union ( union isa_t
) <length 8 bytes/64 bits>
nonpointer
: Indicates whether toisa
enable pointer optimization for pointers
0: pure isa pointer, 1: not only the address of the class object, butisa
also includes class information, reference count of the object, etc.has_assoc
: Associated object flag, 0 does not exist, 1 existshas_cxx_dtor
: Does the object haveC++
orObjc
a destructor, if there is a destructor, you need to do the destructor logic, if not, you can release the object fastershiftcls
: Stores the value of the class pointer. With pointer optimization turned on,arm64
there is a bit in the schema33
to 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 spaceweakly_referenced
: Whether the flag object is pointed to or once pointed to aARC
weak variable, objects without weak objects can be released faster.deallocating
: Whether the flag object is freeing memoryhas_sidetable_rc
: When the object reference count is greater than 10, you need to borrow this variable to store the carryextra_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 itextra_rc
is 9. If the reference count is greater than 10, you need to usehas_sidetable_rc
arrival 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
-
isa
The < > of the class objectobject_getClass(obj)
obtains the metaclass by means of -
isa
The < > of the metaclass canobject_getClass(obj)
get the root class by -
The < > of the root class
isa
canobject_getClass(obj)
get the root metaclass by means of -
The < > of the root metaclass
isa
canobject_getClass(obj)
get the root metaclass by -
Summary: object
isa
-> class, classisa
-> metaclass, metaclassisa
-> root class, root classisa
-> root metaclass, root metaclassisa
-> root metaclass
isa
flow chart
- The dotted line is
isa
the flow chart - The solid line is the class inheritance relationship
NSObject
The parent class of isnil
, and the parent class of the root metaclass isNSObject