The data structure

Class is the structure objc_class

The internal structure is as follows. Note that objc_class inherits from objc_Object, so there should be an ISA inside.

Parameter names type role
isa Class Isa pointer to a metaclass
superclass Class The parent class
chache cache_t Method cache, size determined by internal members
bits class_data_bits_t Some data is stored
data class_rw_t To obtainbitsStored in thedata

1.isa

See isa for details

2,superclass

The name of the variable tells you that it’s a superclass object, so it doesn’t need much explanation

3,cacheMethods the cache

Cache is just what the name implies

Parameter names type The size of the role
_buckets An array of 8 bytes Store a structurebucket_t
_mask mask_tWhich is actuallyuint32_t 4 bytes mask
_occupied mask_tWhich is actuallyuint32_t 4 bytes The number of cached

Now let’s see what bucket_t is. Bucket_t has two member variables, _IMP and key, which are definitely methods and key values. So we can guess, is it possible to obtain the corresponding IMP according to the key, the method call? This also confirms that the method is cached in the cache.

4,bitsdata

As you can see, bits is a 64-bit data segment. What data is stored in it?

Next to bits is a data declaration, which returns exactly the data in bits. But the type is class_rw_t?

4-1 class_rw_tstructure

Methods, properties, and protocols are all familiar to us when we declare classes. But there is also a member variable ro of type class_ro_t that catches my attention

4-2 class_ro_tstructure

Ro also has methods, properties, protocols, and instance variables. Why?

4-3 explorationclass_rw_t

LGPerson as follows

Perform code printing to get the structure of the LGPerson class, and you can see isa and superClass directly. But how do we get class_rw_t and class_ro_t?

The bits can be obtained by offsetting the ISA address 32 bits to the right

Call (” sayHello “, “nickName”, “sayHappy”, “sayHello”, “nickName”, “sayHappy”)

Output properties and you can see the nickName property we declared, as we expected

Output Protrols, which is empty, as expected

So far, compared to the LGPerson file we haven’t seen sayHappy method and member variable hobby, guess where they are stored? Let’s output ro

BaseMethodList is the same as rW’s methods. There is no sayHappy method

Output baseProperties. Unfortunately, hobby is still not found

If we print ivars, we can see that the count is 2, and we can see that both hobby and _nickName are in it

4-4. Class method storage

Where exactly did the sayHappy method go? The difference between sayHappy and sayHello is that sayHello is an instance method, and sayHappy is a class method. This means that instance methods are stored in class objects and class methods are not stored in class objects.

So where do class methods exist? Take a wild guess as to whether class methods exist in metaclass objects. Next, look in the metaclass.

Output a list of methods for the metaclass

4 to 5,bitsandroData duplication problem

Bits store method lists, attribute lists and other member variables. Why do we need ro to store another copy?

The data() method in the objc_class structure can return bits, so we can look up the caller with setData() to see the class assignment process, which might solve this problem.

Find the realizeClass method that executes during compilation, and this should be the original place. The lists in RW should be null at compile time!

So where did the rW data come from? This involves methodizeClass, which adds the class’s method list, protocol list, and property list to the RW.

After methodizeClass is executed, properties, object methods, and protocols in RO are added to RW. This gives you information about the class in the class_rw_t structure. The following structure is formed:

Although found the implementation, but still do not know why so save ah. Now, we need to see when realizeClass is called. Prepare_load_methods caught my eye at this point

Prepare_load_methods is the method that will be called when the class is being loaded, and with methodizeClass we’ll find that all the methods added to the class will be added to RW instead of ro. Ro retains the most primitive data of the class, and subsequent changes cannot penetrate it!

conclusion

At this point, the question has been solved and the class structure has been resolved.

The conclusions are as follows:

  • .hFile declaration properties are generated automaticallysetter,getter, member variables.
  • Instance methods exist in classes, and class methods exist in metaclasses
  • The original method will existroIn, the classification method existsrwIn the