preface

Three years ago, get up the great courage to go out to interview (career move), met the two aspects of the first company is asked to isa and due back at that time the interview questions, can draw the isa bitmap, but actually rote learning, once the interviewer to expand the interview content, you will find that you didn’t understand what the interviewer asked, The final result is definitely going to be passed. Today finally wait to study ISA and class, so oneself must begin to study deeply, a snow three years ago shame.

Begin to explore

This article begins with a formal study of classes and ISA, which ultimately revolves around classes. In fact, the research class is nothing more than the research of the isa bit and the class inheritance relationship of these two, the following 👇 we start from the ISA bit into the topic.

The preparatory work

We need to study classes, so we must first define several classes, here we define two classes, and they had better have an inheritance relationship, convenient for subsequent exploration.

  1. Inheriting from NSObject’s YSHPerson class

  1. The YSHStudent class inherits from YSHPerson

  1. Define two objects in main.m file

The metaclass

What is a metaclass?

  1. A class that takes a class as an example.
  2. The definition and creation of metaclasses are done by the compiler.
  3. The ISA of an object points to a class, which is an object, and the ISA of a class object points to a metaclass.

The definition of a metaclass is too abstract, so let me analyze it with the LLDB code.

Isa walk a

From the above analysis, we can roughly get the isa position:

  • The object of the isaPoint to theclass
  • Class of isaPoint to theThe metaclass
  • Isa metaclassPoint to theRoot metaclass (NSObject)
  • Isa of the root metaclassPoint to theoneself

inheritance

Let’s analyze the inheritance relationship. We can divide it into two kinds:

  1. Class inheritance relationships

Let’s write a function and analyze it by printing information.

From the printed information at 👇, we can see the class inheritance relationship:

A subclass—->The parent class—->The parent class of the parent class—->Root class, NSObject)—->nil

2. The inheritance of metaclasses

Now that we’ve analyzed class inheritance relationships, let’s hazard a guess as to whether metaclasses also have corresponding integration relationships. As usual, let’s write a function first, to make the analysis more intuitive by printing information.

Through the printed information of 👇, we can see that there is also an inheritance relationship between metaclasses, but the inheritance link of metaclasses and the inheritance link of classes are still different.specialThe root metaclass inherits the root class NSObject

The child metaclass—->Father metaclass—->The parent meta-class of the parent meta-class—->Root metaclass (NSObject)—->Root class, NSObject)—->nil

Isa bit & class inheritance summary

According to the above exploration and analysis, we can get that a classic ISA & inheritance bitmap of fatty intestine

Isa walk a

  • Instance objects(the instance of ttf_subclass)isaPoint to theclass(class).
  • Class object(class)isaPoint to theThe metaclass(meta class).
  • The metaclass(meta class)isaPoint to theRoot metaclass (NSObject)(root metal class).
  • Root metaclass (NSObject)(root meta class)isaPointing at itself, forming a closed loop.

Inheritance relationships

  1. Class inheritance
  • classTtf_subclass inherit fromThe parent class(superClass).
  • The parent class(superClass) inherit fromRoot class, NSObject)(rootClass).
  • Root class, NSObject)Inherited fromnilAnd that’s why NSObject is the root class.
  1. Inheritance of metaclasses
  • The metaclass of a subclass(Metal subClass) inherited fromThe metaclass of the parent class(metal superClass).
  • The metaclass of the parent class(Metal superClass) inherited fromA metaclass(root metal class).
  • A metaclass(root metal class) inherited fromRoot class, NSObject)(root class).

Special attention !!!!! Isn’t it true that OC has no inheritance? The inheritance relationship here refers to the inheritance relationship of objects, not classes. Classes are inherited.

Class structure analysis

Memory migration

Before analyzing the structure of a class, we need to know about memory offset, because we need to fetch the contents of the class by memory offset.

  • Ordinary pointer

The print result is as follows:

A and B both point to 10, but the addresses of a and B are different. There is a 4-byte difference between the addresses, because a and B are int types.

  • Pointer to the object

The print result is as follows:

P1 and p2 are also Pointers to the memory address created by [YSHPerson alloc]. &p1 and &p2 are the addresses of Pointers to p1 and p2 objects.

  • Pointer to an array

The print result is as follows:

(1) &c and &c[0] fetch the first address. The difference between &c and &c[1] is 4 bytes (the difference between addresses, depending on the type of data stored). Number of bytes in memory moved by first address = offset * Number of bytes of data type

Class structure exploration

From the objC source code, we can get a rough idea of what’s inside objc_class, as shown below:

Ps: Because there are many methods in the source code, not much use to us, omitted here.

Isa: objc_class inherits from objc_object, so objc_class must also have isa, which is 8 bytes long. Superclass: Class type, essentially a structure pointer, 8 bytes. Cache_t is a type of structure whose memory size is determined by its internal attributes. ④ Bits: the memory size is class_datA_bits_t. The memory size can only be obtained by the memory offset described above.

  1. Calculate the cache memory size

We see that cache_t is a structure, except for static-modified attributes, of which only the two shown in the 👆 screenshot affect its memory size:_bucketsAndMaybeMaskandA consortiumWe can getcache_tThis structure has a memory size of 8+8=16 bytes.

  1. To obtain bits

Before retrieving bits content via memory offset, let’s take a look at the source code. Our bottom exploration idea is: bold guess, careful verification!!

We found an interesting structure in the source code called class_rw_t, which has a couple of properties that we’re very familiar with, method_array_t property_array_t property_array_t, but anyway, I think there are properties and methods in there, Here at 👇 we are officially testing this bold guess.

  • Property list -property_list

We first explore from the attribute list, and specific analysis is shown in the figure below:

So what we found is that property_listOnly attributes.No member variables. So where do member variables go? Let’s explore it step by step.

PS: The difference between an attribute and a member variable isIs there a set/get methodIf yes, it is an attribute. If not, it is a member variable.

  • Method list -methods_list

The method list is explored in the same way as the attribute list, and the LLDB steps are shown below:

We’ll see that in the list of methods onlyInstance methodsAnd properties ofSet/get methods, there is noClass method

  • Member variable -ivars

Property_list only contains properties. Where do member variables exist? In addition to methods, properties, protocols, and ro, we found that the source code of class_rw_t has an ivars attribute of type ivar_list_t. Let’s make a bold guess again: Is the member variable stored in the ivars attribute of type ivar_list_t? So let’s go ahead and verify carefully. 👇 is the LLDB step below:

We get the ivars attribute by printing out the member list exceptsex, as well as_nameand_familyName.

Attributes & Member variables summary

  • Declared via @propertyattribute, stored in the classbits-->data()-->properties()-->list.Contains onlyattribute
  • Declared by {}Member variables, stored in the classbits-->data()-->ro()-->ivarsIn addition to member variables, also includes attributes defined_ Member variables


  • Class method

Methods_list = methods_list = methods_list = methods_list = methods_list At the beginning of our analysis of ISA bitwise, we mentioned the concept of metaclasses, which are used to store information about classes. We can then hazard a guess: is the method stored in the methods_list metaclass? The following steps for LLDB verification are 👇 :

After our layers of verification, we found that our bold guesses are correct!! 💪 💪 💪

Instance method & Class method summary

  • Instance methods of a class are stored in bits–>data()–>methods()–>list, which includes both instance methods and set/get methods for attributes.

  • The class methods of a class are stored in the metaclass bits–>data()–>methods()–>list, where there are only class methods.

conclusion

Learning is actually a process of exploration, in the actual operation step by step to verify our bold guesses, such a learning method has only one disadvantage, that is to improve our understanding of knowledge and deepen the impression of knowledge mastery.