ISA analyzes to metaclass
A previous article on iOS Underground-Object Nature &ISA analysis explored ISA.
Print the pointer to P 0x00000001089C94f0, obtain ISA 0x011D800100008365 according to the pointer address and mask memory offset 0x00007ffffFFFF8 to get 0x0000000100008360. Po gets the current class XHPerson.
Continue to analyze the obtained 0x0000000100008360, perform memory offset 0x00007FFFFFFFFff8 to get 0x0000000100008338, Po to get the current class is also XHPerson. It follows that XHPerson: the class will be infinite with our objects, and there will be more than one class in memory. Verify printing the following code:
Class class1 = [XHPerson Class]; void lgTestClassNum(void){Class class1 = [XHPerson Class]; Class class2 = [XHPerson alloc].class; Class class3 = object_getClass([XHPerson alloc]); Class class4 = [XHPerson alloc].class; NSLog(@"\n%p-\n%p-\n%p-\n%p",class1,class2,class3,class4); } // Result 2021-06-21 15:23:32.247341+0800 002-ISA analysis [13938:273705] 0x100008360-0x100008360-0x100008360-0x100008360Copy the code
0x0000000100008360 is a class, 0x0000000100008338 is not a class. It’s called a metaclass.
Do x/4gx to the metaclass to get 0x00007FFF88a2AC20 and continue with the memory offset 0x00007FFFFFFFFFF8 to get 0x00007FFF88a2AC20 again, Po to get NSObject.
Means currentNSObject
This class ofisa
Point to theNSObject
的 The metaclass
. It can be concluded according to the above analysis.
Isa bitmap and inheritance chain
- Object ISA -> class ISA -> metaclass ISA -> root metaclass ISA -> root metaclass
- Root class ISA -> root metaclass ISA
Isa walk a
Instance objects
The instance of ttf_subclassisa
Point to theclass
The class.class
A class ofisa
Point to theThe metaclass
Meta class.The metaclass
Meta classisa
Point to theA metaclass NSObject
(root metal class).A metaclass NSObject
The root of meta classisa
Pointing at itself, forming a closed loop.
Print the following code,
#pragma mark - NSObject metaclass chain void lgTestNSObject(void){ // NSObject Class Class = object_getClass(object1); // NSObject metaClass = object_getClass(Class); // NSObject rootMetaClass Class rootMetaClass = object_getClass(metaClass); // NSObject rootMetaClass Class rootRootMetaClass = object_getClass(rootMetaClass); NSLog (@ "\ n \ n % p % p instance objects class p metaClass \ n \ n % % p root metaClass \ n % p spikes metaClass", object1, class, metaClass, rootMetaClass, rootRootMetaClass); // pMetaClass = object_getClass(xhperson.class); Class psuperClass = class_getSuperclass(pMetaClass); NSLog(@"XHPerson metaclass %@ - %p",psuperClass,psuperClass); Class tMetaClass = object_getClass(xhteacher.class); // XHTeacher -> XHPerson -> NSObject Class tsuperClass = class_getSuperclass(tMetaClass); NSLog(@"XHTeacher metaclass %@ - %p",tsuperClass,tsuperClass); // NSObject Root Class special case Class nsuperClass = class_getSuperclass(nsobjject); NSLog(@"NSObject metaclass %@ - %p",nsuperClass,nsuperClass); // root metaClass -> NSObject Class = class_getSuperclass(metaClass); NSLog (@ "root metaclass % @ - % p", rnsuperClass, rnsuperClass); } // Result 2021-06-21 16:02:30.535430+0800 002-ISA analysis [14411:327183] 0x108B06850 Instance object 0x7FFF88A2AC48 class 0x7FFF88A2AC20 metaclass 2021-06-21 16:02:30.535501+0800 002-ISA analysis [14411:327183] XHPerson metaclass NSObject - 0x7FFF88A2AC20 2021-06-21 16:02:30.535531+0800 002-ISA analysis [14411:327183] XHTeacher meta-xhPerson - 0x100008338 2021-06-21 16:02:30.535554+0800 002-ISA analysis [14411:327183] NSObject metaclass (NULL) -0x0 2021-06-21 16:02:30.535576+0800 002-ISA analysis [14411:327183] root metaclass nSObjject 0x7FFF88a2AC48Copy the code
Image courtesy of Apple
Superclass inheritance
Class inheritance
class
Ttf_subclass inherited fromThe parent class
SuperClass.The parent class
SuperClass inherited fromThe root class NSObject
RootClass.The root class NSObject
Inherited fromnil
Is that whyNSObject
Is the root class.
Inheritance of metaclasses
The metaclass of a subclass
Metal subClass inherits fromThe metaclass of the parent class
The metal superClass.The metaclass of the parent class
Metal superClass inherits fromA metaclass
Root metal class.A metaclass
Root Metal class inherits fromThe root class NSObject
The root class.
The structure of the class
Memory migration
To analyze the structure of a class, you need to understand the memory offset. When you want to retrieve the contents of the class, you need to obtain the memory offset.
Ordinary pointer
a
andb
They both point to 10, buta
andb
Addresses are different, addresses are different by 4 bytes, becausea
andb
Are allint
Type.
Pointer to the object
p1
andp2
It’s also a pointer that points toXHPerson alloc
Memory address created.&p1
and&p2
Is pointing top1
andp2
The address of the object pointer.
Pointer to an array
&c
and&c[0]
All I get out is the first address.&c
and&c[1]
Difference of 4 bytes (difference between addresses, depending on the type of data stored).- You get the elements out of the array by starting with an offset, which is what we call an offset
The array subscript
. The number of bytes in memory that the first address has moved
=The offset
*Data type Number of bytes
Class structure analysis
From the objC source code, you can get a rough idea of what’s inside objC_class, as shown below:
isa
: Although noted here, butobjc_class
Inherited fromobjc_object
, soobjc_class
There must beisa
Of, 8 bytes.superclass
:Class
Type, essentially a structure pointer, takes 8 bytes.cache
Is:cache_t
Type, we can know through the source codecache_t
Is a structure type whose memory size is determined by its internal properties.bits
Is:class_data_bits_t
Type, the memory size of which cannot be retrieved, can only be retrieved by the memory offset described abovebits
.
Calculate the cache memory size
Go to cache_t
foundcache_t
It’s a structure, minusstatic
Modifier, where only the two in the screenshot above affect its memory size:_bucketsAndMaybeMask
And the union we can getcache_t
This structure has a memory size of8 + 8 = 16
Bytes.
Each member variable in the class has the following memory address
isa
The memory address of is the first address, which was explored earliersuperclass
The memory address of the+0x8
cache
The memory address of the+0x10
bits
The memory address of the+0x20
To obtain bits
Today’s focus is on bits.
Bits.data () should store data, and data() is of type class_rw_t*
Class_rw_t is a structure type that provides methods to get a list of methods, a list of attributes, and a list of protocols. To verify that methods, attributes, and variables are in class_rw_t, add attributes, methods, and member variables to the XHPerson class
Perform LLDB debugging
Attribute to explore
A property declared in a classname
.hobby
Stored in the property list preperty_list_t,p $7.get(0)
andp $7.get(1)
Gets the corresponding properties.
Object method exploration
- Object methods are stored in
XHPerson
A list of methods in a classmethod_list_t
In the water. - The class method is not in
XHPerson
List of methodsmethod_list_t
In the water. p $7.get(x)
The specific value is not available in the method list becausemethod_t
Is processed and passedbig()
Get variables.
Class method inquiry
Object methods are stored in classes, so class methods may be stored in metaclasses. So let’s go with this idea
Class method
Stored in theThe metaclass
In theMethods list
In the water.
conclusion
Class has isa, superclass, cache and BITS member variables. In the process of exploring bits, it is found that bits stores attribute list, method list, member variable list, protocol list, etc. Class methods are stored in metaclass.
Stay tuned for further class analysis.