This is the third day of my participation in Gwen Challenge.

preface

IOS siege lions are probably familiar with alloc and know that it is used to initialize objects, but how does alloc initialize objects? Many people are stuck in this way because they can’t see the underlying implementation in the project. Now let’s explore it

The pointer address and memory of the alloc object

WLWPerson *p1 = [LGPerson alloc];
WLWPerson *p2 = [p1 init];
WLWPerson *p3 = [p1 init];

NSLog(@"%@-%p-%p",p1,p1,&p1);
NSLog(@"%@-%p-%p",p2,p2,&p2);
NSLog(@"%@-%p-%p",p3,p3,&p3);
Copy the code

print

<WLWPerson: 0x600002cd0350>-0x600002cd0350-0x7ffee4b381c8
<WLWPerson: 0x600002cd0350>-0x600002cd0350-0x7ffee4b381c0
<WLWPerson: 0x600002cd0350>-0x600002cd0350-0x7ffee4b381b8
Copy the code
  • We all know thatallocMethod creates an object, and there you have itp1Pointer and allocate memory to the object
  • You can see from the printp1, p2, p3Is the same memory address, and it’s the same object,
  • WLWPersonObject is a0x6In the beginningThe heapon
  • &P1, &P2, &p3Pointer address of,0x7ffee4b381c8, 0x7ffee4b381c0, 0x7ffee4b381b8Continuous spacing8 bytes.
  • &P1, &P2, &p3Are based on0x7At the beginning, it was inThe stackOn, pointing to the same memory space<LGPerson: 0x600002cd0350>

  • Apple’s open source

assembly

You can find the corresponding symbolic method by looking at the assembly code

Open assembly debugging, and then set a breakpoint on the alloc method

Found in the assemblyobjc_allocsymbol

Then add the corresponding symbol breakpoint

Then jump to the corresponding symbol breakpoint

Here we can see the underlying library of alloc libobjc.a.dylib

step into

Hold down thecontrolKey. Click on this

You can also find objc_alloc

Alloc underlying flow

Open the source code and search alloc {to see that the _objc_rootAlloc method is called at the bottom of alloc

_objc_rootAlloc

callAlloc

  • The latest are all using both__OBJC2.
  • checkNilFor the hairfalseBecause there has to beclass, there is no need to check
  • slowpath(checkNil && ! cls)Student: Not this forfalseThe probability is very high
  • fastpath(! cls->ISA()->hasCustomAWZ())trueVery high probability
  • cls->ISA()It’s basically getting the metaclass
  • hasCustomAWZ()Testing forallocWithZone.NSObjectThe default is

_objc_rootAllocWithZone

class_createInstanceFromZone

  • There are three very important functions here
  • instanceSizeCalculates how much memory the object needs to allocate
  • callocAllocate memory
  • initIsaThe object’sisaWith the class
instanceSize

  • Cach. FastInstanceSize,

  • Byte alignment algorithm x + 7&~ 7

  • The byte alignment algorithm is actually 8 byte alignment is the last three bits of zero, is a multiple of 8, can also be moved left and right to (size + 7) >> 3 << 3

size = 10
10 + 7 = 17
0001 0001 (>> 3) -> 000 0010 (<< 3) ->  0001 0000
Copy the code
calloc

The calloc allocation is contained in libmalloc source code, which needs to be analyzed further and then isa is initialized via initIsa

initIsa

The class is then bound to ISA

Isa is divided into two types, one is directly bound to the class, the other is nonponterIsa, because the ISA pointer occupies 8 bits, that is, 64bit, to avoid waste, all isa stores the class address, but also other, this needs to be further studied so that we can open up a memory to store our objects.

What does init new do

initWhat’s going on at the bottom

As can be seen from the source code,initDidn’t do anything. Went straight backself, sointiIt’s just a design pattern to make it easy for developers to rewrite and do things during initialization

thenewwithalloc initWhat’s the difference

It can be seen thatnewIt’s the equivalent ofalloc initIn order to facilitate the expansion of the transmission or as little use as possiblenewTo initialize the object

conclusion

The following is the alloc flow chart

expand

Why is callAlloc called twice

  • callalloc, the first call isobjc_allocRather than_objc_rootAllocAssembly is also seen there, and will be called twicecallAllocThis is because of the callallocWhen forwarding messages,llvmWill put all of thealloc, has been corrected toobjc_alloc

Objc_alloc is called when the version number is greater than 8.0

Why [NSOBject alloc] whencallAllocIt’s only called once

  • The NSObjec class is already called once when the project starts

  • Also, NSObject’s objc_alloc is called once when the program starts, so unlike other classes it doesn’t call callAlloc twice

And fastpath slowpath (x) (x)

#defineFastpath (x) (__builtin_expect(bool(x), 1)) is false with high probability
#defineSlowpath (x) (__builtin_expect(bool(x), 0)) has a high probability of true
Copy the code
  • This instruction was introduced by GCC to allow the programmer to tell the compiler which branch is most likely to be executed. This command is written as:__builtin_expect(EXP, N). It means:EXP==NThe probability is very high
  • This allows the compiler to optimize the code to reduce the performance degradation caused by instruction jumps