review

In the last few posts, we have learned that objects are structs in nature (object nature and class association initIsa(top)), we have learned about struct memory alignment (struct bottom), we have analyzed the source code of alloc bottom (Alloc bottom), and we have learned about instantiating an object. The underlying layer is associated with classes through ISA. But we have not explored the next class, so next, let’s go to the bottom class, to uncover the mystery of class.

Class of

To start with 👇, we instantiate an object and debug at the breakpoint

The class is obtained by printing the address of the object STu, ISA, and then performing an & operation with the mask 0x00007FFFFFFFF8

(lldb) x/4gx stu
0x10072a850: 0x011d800100008339 0x0000000000000000
0x10072a860: 0x0000000000000000 0x0000000000000000
(lldb) p/x 0x011d800100008339 & 0x00007ffffffffff8
(long) $1 = 0x0000000100008338
(lldb) po 0x0000000100008338
JPStudent
Copy the code

So let’s make another guess, class does have an ISA, so synchronize the above operation to see

(lldb) x/4gx 0x0000000100008338
0x100008338: 0x0000000100008310 0x00000001000082c0
0x100008348: 0x00000001006ac3e0 0x000180200000000f
(lldb) p/x 0x0000000100008310 & 0x00007ffffffffff8
(long) $3 = 0x0000000100008310
(lldb) po 0x0000000100008310
JPStudent
Copy the code

Oh my God!

JPStudent, the address is totally different. One is 0x0000000100008338 and the other is 0x0000000100008310. Will classes, like objects, be infinite in memory, with more than one class? So let’s check it out!

//MARK: - Analyze the memory number of class objects
void jpTestClassNum(void){
	Class class1 = [JPStudent class];
	Class class2 = [JPStudent alloc].class;
	Class class3 = object_getClass([JPStudent alloc]);
	Class class4 = [JPStudent alloc].class;
	NSLog(@"\n%p-\n%p-\n%p-\n%p",class1,class2,class3,class4);
}
Copy the code

Print the result

0x100008338-
0x100008338-
0x100008338-
0x100008338
Copy the code

From the printed result, there is only one class, and there is only one class in memory. So 0x0000000100008310 is clearly not a class, so who is it? NSObject is?

The metaclass

(lldb) p/x NSObject.class
(Class) $5 = 0x000000010036a140 NSObject
Copy the code

So instead of NSObject, what is it? It’s a new thing. What is it? We can check it out on MachoOView

In compiling can perform file, in addition to the familiar _OBJC_CLASS_ $_JPStudent, still have one more _OBJC_METACLASS_ $_JPStudent, but my engineering code inside is not to create this? In struct memory alignment (struct low-level exploration), we know that the structure of the object has an ISA that points to the class, so who does the ISA of the class point to? That’s right, pointing to META,

The META class META is generated and compiled by the system

A metaclass

So where does metaclass ISA point to?

(lldb) x/4gx 0x0000000100008310
0x100008310: 0x000000010036a0f0 0x00000001000082e8
0x100008320: 0x000000010072adf0 0x0001e03100000007
(lldb) p/x 0x000000010036a0f0 & 0x00007ffffffffff8
(long) $6 = 0x000000010036a0f0
(lldb) po 0x000000010036a0f0
NSObject
Copy the code

It looks like the metaclass’s ISA points to the root metaclass. Where does the root metaclass’s ISA point to?

From LLDB debugging, you can see that the root metaclass points to itself

Object ISA -> class ISA -> metaclass ISA -> root metaclass ISA

Root metaclass ISA -> root metaclass ISA

Make a picture! It’s hard to understand! Ok, so LET me draw a picture so that you can understand it!

Isa walk a

From the diagram, we can analyze that every object has a metaclass and a root metaclass, and the root metaclass points to itself

Code test validation

	// NSObject instance object
	 NSObject *object1 = [NSObject alloc];
	/ / NSObject class
	 Class class1 = object_getClass(object1);
	 / / NSObject metaclass
	 Class metaClass = object_getClass(class1);
	 // NSObject root metaclass
	 Class rootMetaClass = object_getClass(metaClass);
	 // NSObject Root metaclass
	 Class rootRootMetaClass = object_getClass(rootMetaClass);
	 NSLog(@"\n%p instance object \n%p class \n%p metaclass \n%p root metaclass \n%p root metaclass",object1,class1,metaClass,rootMetaClass,rootRootMetaClass);

Copy the code

Console printing

0x10060d620Instance objects0x10036a1400x10036a0f0The metaclass0x10036a0f0A metaclass0x10036a0f0Spikes metaclassCopy the code

Metaclass inheritance chain

We all know that classes have inheritance relationships, but do metaclasses also have inheritance relationships?

/ / JPPerson metaclass
	 Class pMetaClass = object_getClass(JPPerson.class);
	 Class psuperClass = class_getSuperclass(pMetaClass);
	 NSLog(@"%@ - %p",psuperClass,psuperClass);

	 // JPStudent -> JPPerson -> NSObject
	 // The metaclass also has an inheritance chain
	 Class sMetaClass  = object_getClass(JPStudent.class);
	 Class ssuperClass = class_getSuperclass(tMetaClass);
	 NSLog(@"%@ - %p",ssuperClass,ssuperClass);

	 // NSObject root class special case
	 Class nsuperClass = class_getSuperclass(NSObject.class);
	 NSLog(@"%@ - %p",nsuperClass,nsuperClass);
	 // Root metaclass -> NSObject
	 Class rnsuperClass = class_getSuperclass(metaClass);
	 NSLog(@"%@ - %p",rnsuperClass,rnsuperClass);

Copy the code

Print the result

 NSObject - 0x10036a0f0
 JPPerson - 0x100008300
 (null) - 0x0
 NSObject - 0x10036a140

Copy the code

From the above code and results, metaclasses are also inherited

  • JPPersonClass is the yuanNSObject
  • NSObjectIs the parent classnull, without dad 😂
  • NSObjectThe parent of the root metaclass is0x10036a140This is the same as the one up hereNSObjectClass address of the0x10036a140 Is every bit the same,NSObjectThe root metaclass is pointing againNSObjectThis class.

Everything comes from NSObject, and NSObject points to null, a little bit like tai Chi, out of nothing!

Here’s a picture! The above code looks a bit confusing!

summary

In OC, there are three main types of objects,

  1. instanceObject (Instance objects)
  2. classObject (Class object),Object_getClass (incoming class)Methods to obtain
  3. meta-classObject (Yuan class object),Object_getClass (incoming metaclass)Methods to obtain

Finally, add a more detailed image, the official Image of Apple

The structure of the class

Open Apple’s open source code, you can see the underlying structure of the class

  • By default, there is aISA
  • Pointer to the parent classsuperclass
  • cache
  • bits

thisbitsThere is aclass_rw_t *.class_rw_t There are some method list, property list, member variables and so on information, we look at the source code

So these we are familiar with the class information, how to get, how to view? Check out the next blog analysis…

IOS infrastructure like Discovery (part 2)

🌹 please bookmark + follow, comment + forward, in case you can’t find me next time, ha ha 😁🌹

🌹 welcome everyone to leave a message exchange, criticism and correction, learn from each other 😁, improve themselves 🌹