Initialize the OC object

AppleSVP *a1 = [AppleSVP alloc];
AppleSVP *a2 = [a1 init];
AppleSVP *a3 = [a1 init];
Copy the code

Print pointer:

Print the pointer JONYLog(@"%@--%p",a1,a1);
JONYLog(@"%@--%p",a2,a2);
JONYLog(@"%@--%p",a3,a3);
Copy the code

Results:

Jony: alloc init <AppleSVP:0x600000bbc270>--0x600000bbc270
<AppleSVP: 0x600000bbc270>--0x600000bbc270
<AppleSVP: 0x600000bbc270>--0x600000bbc270
Copy the code

Conclusion: Init does not create new memory space after alloc. Print the address of the pointer itself:

JONYLog(@"%@--%p--%p",a1,a1,&a1);
JONYLog(@"%@--%p--%p",a2,a2,&a2);
JONYLog(@"%@--%p--%p",a3,a3,&a3);
Copy the code

The printed result is:

Jony: alloc init <AppleSVP:0x60000108c190>--0x60000108c190--0x16f283f08
<AppleSVP: 0x60000108c190>--0x60000108c190--0x16f283f00
<AppleSVP: 0x60000108c190>--0x60000108c190--0x16f283ef8
Copy the code

Conclusion: The Pointers themselves have different addresses and are 8 apart.

Second, symbol breakpoint debugging

Add a symbolic breakpoint objc_alloc

Starting a rerun will bring you to objc_alloc

Add a breakpoint at object alloc

Open the assembly debug code

The third kind: add alloc symbol breakpoint arbitrarily through known symbol, determine unknown

[NSObject alloc]

Third, the underlying source code debugging

Objc source code:

To start source debugging, search for the alloc method and locate the nsobject.mm mixed code:Location code:

+ (id)alloc {
    return _objc_rootAlloc(self);
}
Copy the code

Point in:

id _objc_rootAlloc(Class cls)
{
    return callAlloc(cls, false/*checkNil*/.true/*allocWithZone*/);
}
Copy the code

Click in again, the core method:

static ALWAYS_INLINE id
callAlloc(Class cls, bool checkNil, bool allocWithZone=false){#if __OBJC2__
    if(slowpath(checkNil && ! cls))return nil;
    if(fastpath(! cls->ISA()->hasCustomAWZ())) {return _objc_rootAllocWithZone(cls, nil);
    }
#endif

    // N o shortcuts available.
    if (allocWithZone) {
        return ((id(*)(id, SEL, struct _NSZone *))objc_msgSend)(cls, @selector(allocWithZone:), nil);
    }
    return ((id(*)(id, SEL))objc_msgSend)(cls, @selector(alloc));
}
Copy the code

It is not clear whether the _objc_rootAllocWithZone or objc_msgSend method is run at this point

Start by putting breakpoints on your codeAdd three more breakpointsClick to go to the assembly:_objc_rootAllocWithZone, objc_msgSend, and _objc_rootAllocAgain came to _objc_rootAllocWithZoneThere is no callAlloc breakpoint

Reason: Compiler optimization

Hit a break point and run againAdd a breakpointClick on the source and add the breakpointRun and type the current object address

(lldb) p obj
(id) $1 = 0x00000001000083b0
(lldb) 
Copy the code

Click further down

At this point, p is the current obj object

(lldb) p obj
(id) $1 = 0x00000001000083b0
(lldb) p obj
(id) $2 = 0x0000000100e04080
(lldb) 
Copy the code

Conclusion: The address of the object is changed, and the new memory space is reallocated. The memory data above is dirty memory. Add a breakpoint before isaInit:Going down, break point is over isaInitNow p obj and find that the class has been bound:

(lldb) p obj
(id) $1 = 0x00000001000083b0
(lldb) p obj
(id) $2 = 0x0000000100e04080
(lldb) p obj
(ApplePerson *) $3 = 0x0000000100e04080
(lldb) 
Copy the code

Conclusion: At this point you can see that the popoj object is already bound to ApplePerson

LLDB debugging

Rerun the project:

Add a breakpoint and run to a breakpoint:ExtraBytes is 0Click instanceSize to add a breakpointAs you can see, if size is less than 16 it equals 16, and the byte alignment method alignedInstanceSize(), click on it

 uint32_t alignedInstanceSize() const {
        return word_align(unalignedInstanceSize());
    }
Copy the code

Click in again, byte alignment algorithm:

static inline uint32_t word_align(uint32_t x) {
    return (x + WORD_MASK) & ~WORD_MASK;
}
Copy the code

8-byte alignment calculation

(8 + 7) & ~ 7  = 15 & ~ 7  = 8Byte alignment fetch8The integer0000 1111
1111 1000 (7Take the)0000 1000Results =8In fact, it's: move to the right3Let's move it to the left3A (8 + 7) > >3< < again3


0000 0111 (7)
Copy the code

Check the memory

X p a

(lldb) x p
0x1011aa940: b1 83 00 00 a1 21 00 00 00 00 00 00 00 00 00 00. ! .0x1011aa950: 2d 5b 4e 53 54 6f 6f 6c 62 61 72 43 6f 6c 6c 65  -[NSToolbarColle
(lldb) 
Copy the code

Since ios is the small end mode, memory is read from left to right, you can check the memory status by address:

P the address

(lldb) p 0x21a1000083b1
(long) $1 = 36975373484977
(lldb) 
Copy the code

Spell isa_mask Po

(lldb) x p
0x1011aa940: b1 83 00 00 a1 21 00 00 00 00 00 00 00 00 00 00. ! .0x1011aa950: 2d 5b 4e 53 54 6f 6f 6c 62 61 72 43 6f 6c 6c 65  -[NSToolbarColle
(lldb) p 0x21a1000083b1
(long) $1 = 36975373484977
(lldb) po 0x21a1000083b1 & 0x0000000ffffffff8
ApplePerson
Copy the code

NSLog adds breakpoint debugging

ApplePerson *p = [ApplePerson alloc] ;
p.name      = @"kc";
p.nickName  = @"Careful";
p.age       = 18;
p.height    = 10;
NSLog(@"% @",p);
Copy the code

Print memory:

(lldb) x/6gx p
0x1011c46a0: 0x000021a100008499 0x0000000a00000012
0x1011c46b0: 0x0000000100004008 0x0000000100004028
0x1011c46c0: 0x000000020cc639d8 0x0000000000000000
(lldb) po 0x0000000a
10
(lldb) po 0x00000012
18
(lldb) po 0x0000000100004008
kc
(lldb) po 0x0000000100004028(LLDB) Po0x000000020cc639d8
8804252120
(lldb) po 0x0000000000000000
<nil>
(lldb) 
Copy the code

You can see that 10 and 18 share an 8-byte address, which is byte alignment through the above: finally we draw the flow chart of the object’s alloc and init