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:

  1. allocThe underlying execution methods and processes of a method and its core role.
    • Alloc plays a core roleThat is, open up memory, initializeisaPointer and bind the object to the class ISA.
  2. initThe meaning of existence.
    • initIt just comes backobj, nothing else is done 🤣. Because it is a factory method, it exists to enrich the initialization of subclasses.
  3. righttemptationSummary of ideas.(That's the point.)
    • Idea 1: Breakpoints Look at assembly –> BreakpointsStep Over instructionPerform breakpoint symbol lookup.
    • Let’s see if we can do that.Debug ->always show disassemblyAssembly tracks code flow.
    • Thread 3: Direct symbol breakpoint –> Direct to”alloc“For symbolic 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 wangWhen it was created. When the breakpoint stops, hold control willInto aStep into instructionAnd into theallocLook at the execution processallocWhat method will be executed next.Leon ~objc_allocKeep lookingobjc_allocWhat will be done next?And it was all gone. If we don’t see any more useful information, we know what we knowobjc_allocLet’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 wangWhen the breakpoint stops, the operation is performedDebug->Debug workfolw->Always show DisassemblyThe process assembler is clearly tracked.Although assembler a lot of lazy, do not understand assembler,UIPersonNot yet?symbol stub for: objc_allocYou can read it, too. So the rest of the same symbol breakpointobjc_allocI 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 obviousallocIsn’t that the clearest thing we know? That’s rightalloTry 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 totalmethodsFlow 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 oneallocThe underlying implementation of the real core code. So let’s see what’s going on here.

3. Init method implementation

asThe UI wangOutput results,initIt just returns obj and doesn’t do anything else.

4. Differences between alloc_init and new

newMethod underlying call is actually connectedinitIt’s called as well. And compared to the previous exploratory process_objc_rootAlloc 对callAllocIs 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)