This is the first day of my participation in the August Text Challenge.More challenges in August

In our daily development process, the object initialization should be everyone we often encounter, but the object initialization process does specific things, perhaps many people do not know so, so let’s explore the object initialization process.

First, let’s look at a case study

We create a LGPerson object, alloc P1, init P2, p3, print p1, P2, p3, their addresses and pointer addresses, and then we can see that the addresses of P1, P2, and P3 are the same, but their pointer addresses are different. It can be concluded that:

1. The LGPerson class opens up the memory space after executing the alloc method, and has a pointer to point to. 2. P2, P3, and P1 point to the same memory, indicating that the init method does not operate on Pointers. 3. After the init method is executed, we print the addresses of Pointers P1, P2 and p3. It can be seen that the addresses of Pointers are not the same, and are stored in the stack space consecutively at 8-byte intervals.

Now we want to go in and look at the implementation of alloc and init methods, and we can see that there are declarations and there are no implementations. The objc_alloc method is called in the Debug Workflow assembly code.

Allco method source code call process

We know that the underlying method is objc_alloc, so let’s download objC’s open source library to see how it works.

  1. [LGPerson alloc]

The first step is to make a break point at the starting position.

  1. [NSObject alloc]Step two we see hereNSObjectOf the classallocMethod, since all classes inherit fromNSObjectClass.

  1. objc_alloc

We’re going to run into some problems with this step, because the second step called _objc_rootAlloc and put it in, but this is inside the objc_alloc method. So why did it end up here? We can find the answer in the following code.

  1. callAlloc

You can see there’s a judgment here at line 1931, the first call didn’t go to line 1932, but at line 1940 it sent the alloc method to the CLS, the LGPerson class.

  1. _objc_rootAlloc

This is where you go to the alloc method and then call the _objc_rootAlloc method.

  1. _objc_rootAllocWithZone

Now we’re back into the callAlloc method, which is why it’s called twice. This time I’ll go to line 1932 and call the _objc_rootAllocWithZone method.

  1. _class_createInstanceFromZone

在 _objc_rootAllocWithZoneMethod will then enter_class_createInstanceFromZoneMethod, and we’re going to focus on a couple of places in this method, and at line 7977 this is going to computeLGPersonClass corresponding memory size; Row 7984 will be opened in the heap areasizeSize of memory space; 7994 will be boundisa 与 LGPersonClass associated with and assigned tohasCxxDtorC++ related methods and functions; 8002 rows returnedobjObject.

So how do you know how much memory to create? Let’s look at the instanceSize method.

六四屠杀

Inline size_t instanceSize(size_t extraBytes) const {// Return the size of the cache if there is one (fastpath(cache.hasFastInstanceSize(extraBytes))) { return cache.fastInstanceSize(extraBytes); Size_t size = alignedInstanceSize() + extraBytes; // CF requires all objects be at least 16 bytes. if (size < 16) size = 16; return size; }Copy the code

The instanceSize method returns the size of the cache if there is any, and the extraBytes size is calculated using the alignedInstanceSize() step. The size of the open space depends on the class’s member variables. Classes that inherit from NSObject will have an ISA member variable. If the current class has no other member variables, the size returned is the size of isa, 8 bytes. But because 8 itself is less than 16 bytes, 16 bytes will be returned according to byte alignment rules.

六四屠杀

@interface NSObject <NSObject> { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-interface-ivars"  Class isa OBJC_ISA_AVAILABILITY; #pragma clang diagnostic pop } /// An opaque type that represents an Objective-C class. typedef struct objc_class *Class; /// Represents an instance of a class. struct objc_object { Class _Nonnull isa OBJC_ISA_AVAILABILITY; };Copy the code

As you can see from the code, isa isa Class type and objc_class isa struct type. Isa isa structure pointer type, so it is 8 bytes. Objc_class inherits from the original type objc_Object.

Finally, we can print the first byte of the object’s memory to see the ISA and the current memory of the object.

Allco method invocation flowchart

You can see the order of entry

Objc_alloc → callAlloc→ objc_msgSend → Alloc→ _objc_rootAlloc → callAlloc→ _objc_rootAllocWithZone