Latest alloc source code call flow
Look at the methods underlying alloc calls
By looking at assembly analysis, and then in the assembly analysis method to add a symbol breakpoint view
A breakpoint will be added at alloc initialization
Then Debug->Debug Workflow->Always Show Disassembly to see the calls in the assembly
If we look at the assembly, it will stop at the function we are currently executing. If we look at the assembly, it will call the _objc_alloc method
At this point we are adding _objc_alloc by adding a symbolic breakpoint
Moving on, we see that the objC_alloc method is actually executed, and we need to go to the objC source code to see what follows
View objC source code
We’ll start with a working ObjC project, which is downloaded at the end of this article
We entered the alloc call by pressing commd+ and found ourselves directly in objC’s alloc method
Alloc calls _objc_rootAlloc
Objc_rootAlloc continues to call callAlloc
CallAlloc calls the _objc_rooAllocWithZone method
The _class_createInstanFromZone method is called in _objc_rooAllocWithZone for memory allocation and instance object creation
_class_createInstanFromZone calculates the memory size based on the attributes of the object passed in, creates a size OBJ, associates the OBJ with the CLS class, and returns the created object
Memory alignment
In the process of computer coding, there are certain rules for memory allocation. Generally, the memory length is allocated in multiples of 8, but in iOS, it is allocated in multiples of 16.
Due to the small size of memory, memory addresses are generally contiguous during memory allocation. Memory is read in blocks. Therefore, when memory is multiples allocated according to the minimum block size, errors can be prevented during reading.
Isa is the head address of the object in memory. Each pointer is 8 bytes, but the object may also have its own attributes, so the default minimum memory allocation for the initial collection is 16 bytes, and the memory is aligned in multiples of 16.
Here we look at the source code:
If the calculated memory is less than 16 bytes, return 16 bytes
Memory alignment calculation: x+size_t(15))&~size_t(15), the size of the calculated memory is the inverse of the previous 15
If you calculate that you need to allocate 20 memory, the alignment process is as follows
The binary of 20 is 0000 0000 0001 0100
15 binary 0000 0000 0000 1111 +
— — — — — — — — — — — — 0000, 0000, 0010, 0011
~15 binary -1111 1111 1111 0000 &
————0000 0000 0010 0000 == 32
So it’s going to be 20 bytes of memory and it’s going to be 32 bytes of memory aligned
Init source
Init returns its own object and does not create a new object
So why do we even have init methods?
Init method is the constructor of our object initialization, developers can rewrite init method, to reconstruct their own constructor, in the initialization of their own parameters to quickly initialize the object.
New source
And as you can see, new is actually just calling alloc directly and then calling init for us again
So new is the same thing as alloc + init
Look at the principle and look at the code
int main(int argc, const char * argv[]) {
@autoreleasepool {
YJCar *car1 = [YJCar alloc];
YJCar *car2 = [car1 init];
YJCar *car3 = [car1 init];
NSLog(@"%@--%p--%p", car1, car1, &car1);
NSLog(@"%@--%p--%p", car2, car2, &car2);
NSLog(@"%@--%p--%p", car3, car3, &car3);
}
return 0;
}
Copy the code
Car1, car2, car3 are the same object, and they all refer to car1
Print by code log
int main(int argc, const char * argv[]) { @autoreleasepool { YJCar *car1 = [YJCar alloc]; YJCar *car2 = [car1 init]; YJCar *car3 = [car1 init]; Car1.name = @" car1.name "; NSLog(@"%@--%@--%@", car1.name, car2.name, car3.name); car3.name = @"BMW"; NSLog(@"%@--%@--%@", car1.name, car2.name, car3.name); } return 0; }Copy the code
By snooping on memory
(lldb) x car1 0x6000020ff780: e8 55 15 00 01 00 00 00 40 00 15 00 01 00 00 00 .U...... @... 0x6000020ff790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ (lldb) x/4g car1 0x6000020ff780: 0x00000001001555e8 0x0000000100150040 0x6000020ff790: 0x0000000000000000 0x0000000000000000 (lldb) x/4g car2 0x6000020ff780: 0x00000001001555e8 0x0000000100150040 0x6000020ff790: 0x0000000000000000 0x0000000000000000 (lldb) x/4g car3 0x6000020ff780: 0x00000001001555e8 0x0000000100150040 0x6000020ff790: 0x0000000000000000 0x0000000000000000 (LLDB) Po 0x0000000100150040 MercedesCopy the code
The initialization of an int and init’s relationship to alloc and new are just like chopping vegetables
I am also reviewing the bottom knowledge, if this article is helpful to you, I hope you can collect a thumbs-up.
Welcome to discuss with you, thank you!