Welcome to the iOS Basics series (suggested in order)



IOS low-level – Alloc and init explore


IOS Bottom – Isa for everything


IOS low-level – Analysis of the nature of classes


IOS Underlying – cache_t Process analysis


IOS basics – Analysis of the nature of methods and search processes



Alloc and init are known to be the simplest API that we’re most familiar with, but do you know it completely, or is it a stranger that you’re most familiar with? So let’s start with the source code and see what alloc and init do.

To see what a piece of code does, the most direct way to do it is to look at the underlying source code, but you can just click on alloc and see that when you get here, you can’t see the underlying code, there are four ways to do it, okay

1. Set breakpoint: control + in to objc_alloc

Libobjc.a. dylib ‘+[NSObject alloc]:

Debug ->Always Show Disassemby to libobjc.a.dylib ‘objc_alloc:

4. Run directly in the source code, the most convenient but need to be configured, opensource.apple.com/tarballs/ob… Open source objC source, alloc source is in it

1. Start debugging

Register read x0 to read x0 because x0 holds the return object for the x0-x7 function argument

Alloc performed before

Alloc executed

After alloc is executed, x0 stores a pointer to the object, indicating that alloc does have the ability to create memory space, but how much memory space is allocated, step by step click on the instanceSize method

2. Align memory resources

Let’s start with a simple problem, as shown here

Memory alignment

The above code prints: 24,16.

Why does the system allocate different sizes of memory to the same structure? This is the result of allocating memory according to the “memory alignment” rule.

In simple terms, when allocating the StructOne A, it cannot be allocated to the same address with the following 8 bytes of B, so 8 bytes need to be allocated to A for storage. The length of C and D can be stored in the same address at the same time, so the size of StructOne is 8 + 8 + 8 = 24. The length of a, D, and C can be stored at the same address, so the size of StructTwo is 8 + 8 = 16. Of course, the rules of memory alignment are more than that. The rules are as follows:

1: Alignment rules for data members: Struct (or union) data members, the first data member is placed at offset 0, and the starting position of each data member is from the size of the member or the size of the member’s children (as long as the member has child members, such as arrays, Structure, etc.) (for example, if int is 4 bytes, it is stored from the address that is a multiple of 4.

2: Struct as members: If a structure has some struct members, then the struct members are stored from an integer multiple of the size of the largest element in the structure.

The total sizeof the structure, the result of sizeof, must be an integer multiple of its largest internal member. What is lacking must be made up.


Ok, so with memory alignment, let’s see what the system does.

Size of memory requested by the object

8 byte alignment

InstanceSize = (x + 7) &~ 7 (x + 7) = (x + 7) &~ 7 (x + 8) = (x + 7)

X plus 7 times 7 times 7, which is 15 times 7.

1111/0000/15

1111 / / 1000 ~ 7

After the & operation, it is a multiple of 8. The memory size requested by the object is a multiple of 8, and the minimum size is 16, because

if(size <16) size =16;Copy the code

8 byte alignment, CPU read data constantly changing the length of reading is affecting the speed, so in order to speed up the CPU read, you can set a fixed value, with space for time, because the 8 byte data type is more, so 8 bytes to its calculation


When the register_notification mapping file is loaded, dyLD loads the structure of the class. The structure of the class contains the whole data segment, and there is ro in the data. Ro has ivar_list, PROTOCOL_list, etc., get class information, do byte alignment, 8 byte alignment

The size of memory allocated by the system

The value defined by the macro

Let’s say that this object has five 8-byte attributes, so the sISE that’s passed in here is 40, the algorithm above

k = (size + NANO_REGIME_QUANTA_SIZE - 1) >> SHIFT_NANO_QUANTUM;
slot_bytes = k << SHIFT_NANO_QUANTUM;Copy the code

That is, slot_bytes = (40 + 16-1) >> 4 <<4. In this case, the algorithm of moving 4 bits to the right and 4 bits to the left is used for 16-byte alignment. Therefore, when the memory size requested by the object is 40, the memory size allocated by the system is aligned with 16 bytes and the required complement is 48.

Summary: The size of memory requested by an object is not necessarily the same as the size allocated by the system

8-byte alignment – Attributes within the object 16-byte alignment – the object itself

The reason for this design is that if you give the object just the right size, you may overflow at some point and need to leave some threshold

3. Initialize isa

After memory allocation, it goes to

obj->initInstanceIsa(cls, dtor);Copy the code

What it does is bind objects and classes through an ISA, which contains a lot of class information, and it assigns an owner to this space.

4. The init the bottom

Alloc basically does that, but init, let’s look at the bottom of init.

Init source code

The underlying source code for init is as simple as that; it simply returns the object and does nothing. In theory, init is useless code that should not be written, but it is usually done for the sake of development custom and specification, and init is a factory design that subclasses can override from the definition.


Conclusion:


Alloc: Alloc allocates space in memory by means of memory alignment and initializes isa. It is equivalent to building a house of a fixed size and identifying the owner of the house.

Init: Init returns the object itself without any additional operations. Because it does nothing, it is more developer-friendly and can be overridden at will, providing developers with an initial interface. Equivalent to letting developers enjoy the inside of the house to do fine decoration.