preface

As we all know, OC language is an object-oriented language highly encapsulated to C language. In our development process, we can constantly create a class, and then declare a object to use. However, we rarely pay attention to how objects are reflected in the bottom layer. So today, let’s explore how objects are reflected in the bottom layer together with me!

Step 1: The method of exploration

1. Introduction of Clang

Yet? Day by day strange, what is Clang? If you want to know more about Clang, you can go to Google or Baidu. We won’t go into this article.

This is a short introduction to Clang, so how does it work? Watch officers go down;

2. Run the Clang command to recompile the OC file into a C++ file

To convert the main.m file into a c++ file, run clang-rewrite-objc main.m -o main. CPP. Such as:

Before the conversion, we had only one main.m file in this directory. When we execute clang we get a main. CPP file; The following

Step 2: What does the subject look like at the bottom?

First we create a LGPreson class in our main.m file;

Then we open the CPP file that we obtained by executing the clang command; Type LGPreson and we can find the code:

From the code in this image, we can see that objects in oc exist as structures at the bottom; At this point, you might wonder, well, we usually create classes that have properties, but how do they exist here?

Here we declare a personName attribute, and we’re re-executing clang:

From this we can see that the properties declared in a class also exist at the bottom as properties of a structure;

If we look at the LGPerson_IMPL structure, in addition to our own declared attribute _personName, we can also see another attribute NSObject_IVARS. What is that? By searching NSObject_IMPL we can see the code:

As you can see from this code, this structure holds the isa that we often talk about; Are you surprised that the famous Isa is here? Isa is of Class type, and what is Class? We continue to type Class in the input box and scroll down one by one until we find the following code in a corner:

Until we saw it, a pointer to Class, and a pointer to id, both of which are of type objc_class, we were thinking, “How nice is id? Every other object declaration needs an asterisk, but id doesn’t.” Do you feel cheated when you see two lines of underlying code? Id itself is a pointer type! At the same time, did he nod his head meaningfully and say “so dei Sne”?

Conclusion:

Therefore, we can conclude that the object in oc exists as a structure at the bottom, and in the structure of each object there is an NSObjct_IVARS that inherits the parent structure. This property is the ISA of the OC object, which is also the starting position of the object when allocating memory.

Knowledge extension: relationships among structures, bit-fields, and unions

First let’s look at the following code:

We can see that the Car structure has four attributes, all of which are BOOL, and a BOOL takes up one byte in memory allocation, so we can see that the Car structure takes up four bytes in memory, and we also know that each byte takes up eight bits, 4 bytes total 32 bits (0000 0000 0000 0000 0000 0000); But if we take a closer look, there are only two states of BOOL: YES and NO, and a BOOL does what it does with one bit, so for these four properties, we can use a 4-bit binary class for 0X 1111; If we were to allocate four bytes, this would waste a lot of memory; Since there is at least one byte of memory, we can allocate one byte to this structure instead of four bytes. How can we keep this structure to one byte of memory? Hence the concept of bit-fields;

Using bit-field control, we add: and bits (how many bits are in this attribute) after each attribute:

Now if we print by sizeof(car) we get a 1, so we can optimize memory a lot;

Let’s look at another piece of code:

In this code we can see that we have a structure for LGTeacher1, and we have declared a Teacher1 object, and we have assigned the name and age of teacher1 to the object. At this point we can see through the p Teacher1 command that the name of the object, And age already have the values we assigned to them earlier;

We are looking at another piece of code:

We have a union of LGTeacher2, we declare a Teacher2 object, and assign the name and age of the object to teacher2. At this point we can see with p Teacher2 command, When the code reaches Teacher2. name = “Cooci”, we can see through p Teacher2 that the name has been assigned successfully, but when we continue to execute teacher2.age = 18 we can see through P Teacher2. We can see that name is gone, and age is 18, and we can see that name and age share the same piece of memory, and they’re mutually exclusive;

From these two pieces of code we can draw the following conclusions:

The attributes in the structure are co-existing, and each attribute has its own memory, but it is easy to cause the problem of memory waste. Although the bit-domain can be optimized appropriately, it cannot be completely cured. The attributes in the consortium share the same piece of memory, so the attributes in the consortium are mutually exclusive. Although the memory is saved, the attribute values cannot coexist.