The analysis of the class
The isa of an object refers to a class. Everything is an object. The class is also an object. This class is the metaclass defined by Apple
metaClass
Existence is reasonable, where is the significance of the existence of metaclass?
int main(int argc, char * argv[]) {
@autoreleasepool {
Class class1 = [SWPerson class];
Class class2 = [SWPerson alloc].class;
Class class3 = object_getClass([SWPerson alloc]);
Class class4 = [SWPerson alloc].class;
NSLog(@"\n-%p-\n-%p-\n-%p-\n-%p-",class1,class2,class3,class4);
}
return} Result: -0x100009510-
-0x100009510-
-0x100009510-
-0x100009510-
Copy the code
- The addresses of class objects are the same, and each class has only one piece of memory, which is obviously different from ordinary objects
Is_mask = is_mask = is_mask = is_mask = is_mask = is_mask = is_mask = is_mask = is_mask = is_mask = is_mask = is_mask = is_mask = is_mask = is_mask = is_mask = is_mask = is_mask = is_mask = is_mask = is_mask Define ISA_MASK 0x00007ffffffffff8ULL arm64: define ISA_MASK 0x0000000ffffffff8ULL arm64 (Simulators) : define ISA_MASK 0x007ffffffffffff8ULL
- P /x swPerson. class gets the memory address of the class object 0x00000001000080E8, and x/4gx formats the memory address of the class object
- P /x 0x00000001000080C0&0x00007ffffFFFFff8 set the first address of the class object (ISA pointer address)0x00000001000080c0 and ISA_MASK, We get a new memory address 0x00000001000080c0
- Po 0x00000001000080C0 prints the address data and gets SWPerson
0x00000001000080E8 and 0x00000001000080C0 are two different addresses. 0x00000001000080E8 is a class address, and the class corresponding to 0x00000001000080C0 is called a metaclass
summary
- Metaclasses are created automatically by the system compiler, independent of the user
- The ISA of an instance object points to a class, and the ISA of a class object points to a metaclass
- The name of a class is the same as the name of its associated metaclass (only associated metaclass has a class name)
Isa bitmap analysis
Apple official ISA location and inheritance chart
- Isa –> class object of instance object
- Isa –> metaclass for class objects
- Metaclass ISA –> root metaclass
- Isa of the root metaclass –> root metaclass (pointing to itself)
Class metaclass root metaclass inheritance diagram
int main(int argc, char * argv[]) {
@autoreleasepool {
Class tMetaClass = object_getClass(SWTeacher.class); / / SWTeacher metaclass
Class tMetaSuperClass = class_getSuperclass(tMetaClass);// the parent of SWTeacher's metaclass
Class pMetaClass = object_getClass(SWPerson.class); / / SWPerson metaclass
Class pMeatSuperClass = class_getSuperclass(pMetaClass);// The parent of SWPerson's metaclass
Class nMetaClass = object_getClass(NSObject.class); / / NSObject metaclass
Class nSuperClass = class_getSuperclass(NSObject.class);/ / parent class NSObject
Class nMetaSuperClass = class_getSuperclass(nMetaClass);// the parent of NSObject's metaclass
NSLog(@"SWTeacher-%p",SWTeacher.class);
NSLog(@"SWPerson-%p",SWPerson.class);
NSLog(@"NSObject-%p",NSObject.class);
NSLog(@"%@ - %p - %@ - %p",tMetaClass,tMetaClass,tMetaSuperClass,tMetaSuperClass);
NSLog(@"%@ - %p - %@ - %p",pMetaClass,pMetaClass,pMeatSuperClass,pMeatSuperClass);
NSLog(@"%@ - %p - %@ - %p",nMetaClass,nMetaClass,nMetaSuperClass,nMetaSuperClass);
}
return
}
SWTeacher-0x100009618
SWPerson-0x100009528
NSObject-0x7fff8deb3118
SWTeacher - 0x1000095f0 - SWPerson - 0x100009500
SWPerson - 0x100009500 - NSObject - 0x7fff8deb30f0
NSObject - 0x7fff8deb30f0 - NSObject - 0x7fff8deb3118-- -- (null)
Copy the code
The parent class of NSObject prints nil. The parent of SWTeacher’s metaclass is the metaclass of SWPerson (the address of the metaclass of SWPerson is different from the address of the SWPerson class). The parent of the metaclass of SWPerson is the metaclass of NSObject, and the parent of the metaclass of NSObject is NSObject (same address as NSObject)
SWTeacher
inheritanceSWPerson
.SWPerson
inheritanceNSObject
.NSObject
Is the parent classnil
SWTeacher
Yuan class inheritanceSWPerson
Metaclasses,SWPerson
inheritanceA metaclass
.A metaclass
inheritanceNSObject
Class structure analysis
Isa is of Class type, Class is objc_class*, objc_class isa structure, all the underlying implementation of Class is objc_class
struct objc_class : objc_object {
...
// Class ISA;
Class superclass;
cache_t cache; // formerly cache pointer and vtable
class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags
// Here are some methods to omit};Copy the code
Objc_class inherits from objc_Object, which has only one member variable isa. We’ve already explored what isa does. The specific function of the following three member variables is unknown, how to explore it? The address of the class is known, so get the address of the inside member variable based on the first address + offset value explored above, and then get the value. But offset values need to know the sizes of all member variables before the current variable
isa
The structure pointer takes 8 bytesClass superclass
Also, the structure pointer takes 8 bytescache_t cache
Is the size of the struct type, determined by the struct body member variable. 16 bytesclass_data_bits_t bits
Knowing the size of the first three member variables, we can get the address of the bits
Cache_t Memory size
typedef unsigned long uintptr_t;
#if __LP64__
typedef uint32_t mask_t; // x86_64 & arm64 asm are less efficient with 16-bits
#else
typedef uint16_t mask_t;
#endif
struct cache_t {
private:
explicit_atomic<uintptr_t> _bucketsAndMaybeMask; / / 8
union {
struct {
explicit_atomic<mask_t> _maybeMask; / / 4
#if __LP64__
uint16_t _flags; / / 2
#endif
uint16_t _occupied; / / 2
};
explicit_atomic<preopt_cache_t *> _originalPreoptCache; / / 8
};
// Here are some methods to omit
};
Copy the code
Cache_t is a structure type with two member variables _bucketsAndMaybeMask and a union
_bucketsAndMaybeMask
Uintptr_t unbroken long integer type of 8 bytes- The union has two member variable structures and
_originalPreoptCache
The memory size of the union is determined by the maximum variable type in the member variable _originalPreoptCache
The structure pointer is 8 bytes- It’s in the structure
_maybeMask
._flags
._occupied
._maybeMask
Uint32_t takes up 4 bytes,_flags
and_occupied
Is the Uint16_t each of 2 bytes, structure size is 8 bytes cache_t
The memory size of 8+8 or 8+4+2+2 is 16 bytes
Summary: By fetching class_rw_t* data(), you get the methods, properties, protocols, deepCopy, ro, and so on for that class
class_rw_t
struct class_rw_t {
// Be warned that Symbolication knows the layout of this structure.
uint32_t flags;
uint16_t witness;
#if SUPPORT_INDEXED_ISA
uint16_t index;
#endif
// Some code is omitted
explicit_atomic<uintptr_t> ro_or_rw_ext;
Class firstSubclass;
Class nextSiblingClass;
class_rw_ext_t *deepCopy(const class_ro_t *ro) {
return extAlloc(ro, true);
}
const method_array_t methods() const {
auto v = get_ro_or_rwe();
if (v.is<class_rw_ext_t *>()) {
return v.get<class_rw_ext_t *>(&ro_or_rw_ext)->methods;
} else {
return method_array_t{v.get<constclass_ro_t *>(&ro_or_rw_ext)->baseMethods()}; }}const property_array_t properties() const {
auto v = get_ro_or_rwe();
if (v.is<class_rw_ext_t *>()) {
return v.get<class_rw_ext_t *>(&ro_or_rw_ext)->properties;
} else {
return property_array_t{v.get<constclass_ro_t *>(&ro_or_rw_ext)->baseProperties}; }}const protocol_array_t protocols() const {
auto v = get_ro_or_rwe();
if (v.is<class_rw_ext_t *>()) {
return v.get<class_rw_ext_t *>(&ro_or_rw_ext)->protocols;
} else {
return protocol_array_t{v.get<constclass_ro_t *>(&ro_or_rw_ext)->baseProtocols}; }}};Copy the code
Attributes of a class
Member variable acquisition process: nsobject. class -> class_data_bits_t -> class_rw_T -> property_array_t -> property_list_t -> property_t
Class instance method
Nsobject. class -> class_data_bits_t -> class_rw_T -> method_array_t -> method_list_t -> method_t -> BIG
Member variables
Nsobject. class -> class_datA_bits_t -> class_rw_T -> class_ro_t -> ivar_list_t -> ivar_t
The underlying implementation of a variable isivar_t
. Stored in theclass_ro_t
The system automatically generates a band for the property in the variable list_
Property name variable, stored inclass_ro_t
In a list of variables
Class method
Class method acquisition process: NSObject.class -> metaClass -> class_data_bits_t -> class_rw_t -> method_array_t -> method_list_t -> method_t -> big
Conclusion: Class methods are stored inYuan class
In the list of methods
The source code
View the source code isObjc4-818.2. Tar. Gz