Believe most iOS developers every day is immersed in a project business logic code and perfect, due to the underlying learning for business logic itself didn’t too much, so know little about the underlying knowledge, also causes our iOS developers reached a basic employment bottlenecks, high inadequate low not, therefore studying the underlying knowledge is your challenge well-paid, The only way to get to the top of iOS developers; We not only need to be able to write business logic code, but also to master the principles of its underlying compilation process, so let’s set foot on the road of low-level learning.

“Kc: Pretty boy, huh! Strange…”

In development, when we create an object, it’s usually *[[LhkhPerson alloc]init]*

Have you ever wondered why you’re doing this? So what did Alloc do?

The role of the alloc

With that in mind, let’s explore what alloc does when the object is initialized…

First let’s look at a demo example:

We’ve defined an LhkhPerson class here, alloc an object P, init two objects P1, p2, so what’s the relationship between these three? Next, let’s look at the print by running it:

The print is divided into two pieces, which can look like this diagram

  • From the first block we can see that they are all identical in content and address. When class alloc creates an object, it creates a memory space, and all three objects point to that address memory space;
  • We can see from the second block that when an object is init it doesn’t actually open up new memory space, it just has its own pointer address on the stack, and they’re sequential.

Now that we know what alloc does, we want to say, how does alloc work, what’s the process inside, so let’s look at the alloc process again:

When we click to see the alloc implementation source code

😭, do not panic, look at the underlying alloc process we have many methods, let’s take a look at the following:

Method 1: Use the symbol short point

Method 2:The assembly and process then confirm the call symbol, again combined with the breakpoint follow up

Method 3: Break the key alloc by using a symbolic breakpoint

Methods…

There are many ways to explore the underlying source code, but we should find that all of these ways are a little tedious to explore. Is there any easy way? That must be some ah, by directly compiling the underlying source code to achieve.

As we explore above, we can find that objc_alloc is actually in the LibobJC library, so we can find objC4 by apple official and see that the current source code is 824, so we use the previous version 818.2, drive;

Ps: 818.2 version of the underlying source compilation can be successful please refer to the Github configuration of cool C.

Alloc Low-level exploration

Above:

We cut off the alloc call by compiling the objc source code

And then we get to the main point

  1. So let’s hold Command and clickallocMethod, then jump to the + (id)alloc{} method in the nsobject.mm (.mm is a c++ file) file, and you can see that an intermediate method _objc_rootAlloc is called with the current class as an argument

2. Click the command_objc_rootAllocFollowing up, you can see that the intermediate method is invokedcallAlloc 3. Click the commandcallAllocFollow up with three parameters,cls(current class),checkNilCallAlloc = false; callAlloc = false; callAlloc = false;allocWithZone(For the allocWithZone method, check the official Apple documentation to see why the alloc method is the same, but for historical reasons it is not used)

The core method first determines __OBJC2__ is not objc2.0, if it is objc2.0 then two macros will follow:

  • Slowpath: Tells the compiler there is a high probability that the condition passed in will turn out to be false
  • Fastpath: Tells the compiler that it is highly likely that the condition passed in will turn out to be true

Then go into the _objc_rootAllocWithZone method

Click on _objc_rootAllocWithZone to jump to this method

5. Then command clicks the _class_createInstanceFromZone method

Through the analysis we can find that there are three core methods

  1. instanceSizeCalculate how much memory you need to open up
  2. callocOpen up memory space
  3. initInstanceIsaAssociate OBj’s ISA with the class

Let’s take a look at this method:

  • InstanceSize Specifies the memory size

How do you calculate memory size? What determines the memory size of our objects in general? (An object may contain attributes, member variables, methods, protocols, isa, etc., which determine the size of the object’s memory is the member variables, nothing else.)

When we first printed LhkhPerson without an instance variable, we saw an 8, so where did this 8 come from? Because LhkhPerson is inherited from NSObject, and NSObject has a Class isa in it, and that Class isa struct pointer type, so it’s 8.

  1. So we know that the 8 bytes size comes from the NSObject inheritance;
  2. Let’s go ininstanceSizeMethod,if(size<16) size = 16;We can get at least 16, or less than 16 we can just get 16;

Word_align (x + WORD_MASK) & ~WORD_MASK (x + WORD_MASK) & ~WORD_MASK (x + WORD_MASK) UnalignedInstanceSize = unalignedInstanceSize = unalignedInstanceSize = unalignedInstanceSize = WORD_MASK = 7

15 0000 1111 7 0000 0111 ~7 1111 1000 15&~ 7 0000 1111&1111 1000 0000 1000 -->8 <<3 0000 1000 >>3 0000 0001 0000 0001 <<3 0000 1000Copy the code

So you can see that it’s 8 bytes aligned, take integer multiples of 8, erase anything less than 8;

4. 3. The World CupfastInstanceSizeMethod to find one of themalign16(size + extra - FAST_CACHE_ALLOC_DELTA16)Algorithm, then let’s follow upalign16In the method

According to the above byte alignment method, we can see that it is actually 16 bytes alignment, take integer multiples of 16, less than 16 erase; So why byte alignment? Why is it 16 bytes aligned?

Round space for time

  • We know that the CPU reads in byte blocks, and if we don’t follow the byte alignment scheme, it will slow down the CPU’s performance.

  • The reason for 16-byte alignment is that isa is 8 bytes in the object itself. If isa is 8 bytes in the object itself, then isa will be next to each other, causing confusion. It’s also not suitable for larger numbers. After all, if an object really only has one ISA property, it’s not appropriate to use 32 bytes, wasting memory.

  • Create obj and open up memory space

  • Associate OBj’s ISA with the class

When we first created obj, we puck obj to get an address, and notice that we just created obj but we didn’t allocate the actual memory space, so this is dirty memory

And then we go to the next step when we get to the Calloc method, we go to the next step

But at this point you’ll notice that obj is still of type ID, so how does that relate to our LhkhPerson? Let’s go

And then finally when you return out this obj that’s an object alloc is done.

conclusion

Alloc is basically calculating the size of the memory, opening up the memory space, isa associated with the class.

At last, please point out any mistakes. Our ability is limited. Learn from each other.