Writing in the front
As an iOS coder who has been writing business code for years, I have to create classes and objects, and ALLOc init is used very frequently. So what exactly do alloc and init do. With questions, let’s explore.
XHPerson *x0 = [XHPerson alloc];
XHPerson *x1 = [x0 init];
XHPerson *x2 = [x1 init];
NSLog(@"x0==%@--%p--%p", x0, x0, &x0);
NSLog(@"x1==%@--%p--%p", x1, x1, &x1);
NSLog(@"x2==%@--%p--%p", x2, x2, &x2);
Copy the code
What happens if you create three objects and print their contents, object addresses, and pointer addresses separately?
x0==<XHPerson: 0x1013a2770>--0x1013a2770--0x7ffeefbff468
x1==<XHPerson: 0x1013a2770>--0x1013a2770--0x7ffeefbff470
x2==<XHPerson: 0x1013a2770>--0x1013a2770--0x7ffeefbff460
Copy the code
As you can see, the contents and addresses of the three objects are the same, and the pointer addresses are different.
Conclusion: 1. Alloc has a memory pointer to it. 2. Init indicates the same memory and does not operate on the pointer. 3. Alloc opens memory, init does not open memory
Alloc source
So now that alloc is doing the memory thing, how does it do it? Init doesn’t do anything? What’s the point? Keep going down. Source code process:
1.alloc
+ (id)alloc {
return _objc_rootAlloc(self);
}
Copy the code
2._objc_rootAlloc
id
_objc_rootAlloc(Class cls)
{
return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/);
}
Copy the code
3.callAlloc
static ALWAYS_INLINE id callAlloc(Class cls, bool checkNil, Bool allocWithZone=false) {#if __OBJC2__ //objc2.0 // cls)) return nil; If (fastPath (!) {// If (fastPath (!); cls->ISA()->hasCustomAWZ())) { return _objc_rootAllocWithZone(cls, nil); } #endif // No 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
4._objc_rootAllocWithZone
id
_objc_rootAllocWithZone(Class cls, malloc_zone_t *zone __unused)
{
// allocWithZone under __OBJC2__ ignores the zone parameter
return _class_createInstanceFromZone(cls, 0, nil,
OBJECT_CONSTRUCT_CALL_BADALLOC);
}
Copy the code
5._class_createInstanceFromZone (core instance creation method)
Three important things are done, which can be seen more clearly with screenshots
Object creation process
1. 'CLS ->instanceSize' calculates the memory size. 2. '(id)calloc(1, size)' opens memory. 3. 'obj->initInstanceIsa(CLS, hasCxxDtor)' associates the class with memory.Copy the code
InstanceSize method
FastInstanceSize method
Align16 method, 16-byte memory alignment
Caches free alignedInstanceSize method
Calloc method
Calloc opens up memory without executing the defined class
InitInstanceIsa method
Initialize ISA. The underlying mechanism of ISA is not analyzed.
The last
Alloc flowchart
conclusion
Through the analysis of alloc source code, it can be known that the main purpose of Alloc is to open up memory and associate ISA and CLS classes. There are three core steps to open up memory: calculate memory size, apply for memory space, and associate ISA and CLS classes