IOS has been in development for a few years and is still a UI guy. Alloc has been done countless times, but the underlying implementation still doesn’t know much about it.
Center of this paper:
alloc
The underlying execution methods and processes of a method and its core role.- Alloc plays a core roleThat is, open up memory, initialize
isa
Pointer and bind the object to the class ISA.
- Alloc plays a core roleThat is, open up memory, initialize
init
The meaning of existence.init
It just comes backobj
, nothing else is done 🤣. Because it is a factory method, it exists to enrich the initialization of subclasses.
- right
temptation
Summary of ideas.(That's the point.)
- Idea 1: Breakpoints Look at assembly –> Breakpoints
Step Over instruction
Perform breakpoint symbol lookup. - Let’s see if we can do that.
Debug
->always show disassembly
Assembly tracks code flow. - Thread 3: Direct symbol breakpoint –> Direct to”
alloc
“For symbolic breakpoints.
- Idea 1: Breakpoints Look at assembly –> Breakpoints
There is an object called UI child
Run the UI and run a daily print run to see the results:
#import "ViewController.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"i'm coming");
UIPerson *nickname = [UIPerson alloc];
UIPerson *firstname = [nickname init];
UIPerson *lastname = [nickname init];
NSLog(@"nickname-%@-%p",nickname,nickname);
NSLog(@"firstname-%@-%p",firstname,firstname);
NSLog(@"lastname-%@-%p",lastname,lastname);
}
@end
Copy the code
The three Pointers point to the same address, so the alloc has already allocated memory, and the init call seems to have no effect on the address of the pointer. So let’s test the alloc, init implementation process.
Practice to serve
Idea 1: Break point step-into-instruction
Just like normal breakpoint debugging, hit the breakpoint toThe UI wang
When it was created. When the breakpoint stops, hold control willInto aStep into instructionAnd into thealloc
Look at the execution processalloc
What method will be executed next.Leon ~objc_alloc
Keep lookingobjc_alloc
What will be done next?And it was all gone. If we don’t see any more useful information, we know what we knowobjc_alloc
Let’s see what happens with a sign breakpoint.With a break point,Continue progress executionLeave you ~Finally got thelibobjc.A.dylib'objc_alloc
, write down ~
Idea 2: Debug Disassembly
Still break point toThe UI wang
When the breakpoint stops, the operation is performedDebug
->Debug workfolw
->Always show Disassembly
The process assembler is clearly tracked.Although assembler a lot of lazy, do not understand assembler,UIPerson
Not yet?symbol stub for: objc_alloc
You can read it, too. So the rest of the same symbol breakpointobjc_alloc
I can get it againlibobjc.A.dylib'objc_alloc
.
Idea 3: Cut to the chase
Let’s suppose — let’s suppose that none of the other methods are obviousalloc
Isn’t that the clearest thing we know? That’s rightallo
Try a symbol breakpoint and see what happens?Oh ho ~ clean and clean got itlibobjc.A.dylib'objc_alloc
.
Theory to serve
Through the above three ideas of alloc analysis, it is concluded that the underlying implementation of alloc is in LibobJC, then if you can find libobJC source code, the rest is still a problem? Still have to grumble 1: before coming to libobjc, why a few tentative ideas so many words? In fact, in the process of testing the most difficult is not the underlying code is difficult to understand, but do not know how to start, want to see what….
-
First, go to the Apple open source code address (download objC4), only according to the known symbol to search the method name globally, method flow that can only rely on association, hard in full of bitterness.
-
Second, go Cooci configuration – compiles apple official source objC! Download the compiled versions of objC4 source code, that is, can command method name jump, can also run up with breakpoints, for the underlying exploration of other methods is also very convenient.
1. Alloc execution process
Get the source code and start from[NSObject alloc]
Method Start layer by layer start down test, first Po a totalmethods
Flow chart:
2. Alloc method tracking
See _objc_rootAlloc in nsobject. mm
+ (id)alloc {
return _objc_rootAlloc(self);
}
Copy the code
id _objc_rootAlloc(Class cls){
return callAlloc(cls, false/*checkNil*/.true/*allocWithZone*/);
}
Copy the code
CallAlloc is a distribution method that opens up the core method of memory encapsulation. Ps: There’s more fun in this
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
// 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));
}
//---------------
NEVER_INLINE
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
This is the real onealloc
The underlying implementation of the real core code. So let’s see what’s going on here.
3. Init method implementation
asThe UI wang
Output results,init
It just returns obj and doesn’t do anything else.
4. Differences between alloc_init and new
new
Method underlying call is actually connectedinit
It’s called as well. And compared to the previous exploratory process_objc_rootAlloc
对callAlloc
Is exactly the same, so there is no difference between the two.
conclusion
The main record of the important test ideas, step by step to get the source code, and finally determine the basic flow of alloc, its core role is to open up memory, initialization Isa pointer and object and class binding. Init returns obj and does nothing else 🤣, new looks awesome.
Finally, there are points in the exploratory process that can be expanded, such as instanceSize, the internal implementation of initInstanceIsa, etc., which I will update in another article.
Summary of resources in the process
Cooci Configuration – Compiles apple official source code objC!
Apple Open source address (download objC4)