IOS Startup Process

  • Dyld start—–libsystem—–libdispatch—-GCD environment preparation ——libObjc (_objc_init)

Download the source code

  • Alloc process analysis, source code is essential, through the source code we can see the call process step by step.
    • Official source, select macOS ->11.3 -> objC4-824 to download
    • God compiled good source code

Alloc method debugging

Method 1: Run the symbol breakpoint on the alloc line and then run the symbol breakpoint alloc (set to disable, otherwise NSObject’s alloc will be broken). Commond + setp into Conclusion: P1, P2, P3 point to the same piece of memory space, their pointer addresses are different, but in the stack is a piece of continuous memory space method 2: through assembly debugging enable assembly debugging modeControl + step into(single step debugging), determine the next step using the function objc_allocLower sign breakpointRun the program again to get a symbolic breakpoint _objc_rootAllocWithZone, and so on to get the entire call flow

Source code analysis

Alloc entrance

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

Click _objc_rootAlloc

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

Click callAlloc

static ALWAYS_INLINE id callAlloc(Class cls, bool checkNil, Bool allocWithZone=false) {#if __OBJC2__ if (slowPath (checkNil &&! 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

Click _objc_rootAllocWithZone

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

Click _class_createInstanceFromZone to go to the core code, three core points

  • The size of the object is determined by the member variable, and when you open up memory,
    • 8-byte alignment, integer multiples of 8 (reason: when there are no variables, only ISA exists, 8 bytes), CPU reads faster, trading space for time
    • Clean memory ro data()->ro()->instanceSize
    • Memory alignment means that 8 bytes of space is not wasted. For example, ints occupy 4 bytes and chars occupy 1 byte, they are allocated to the same 8-byte space
    • Po is printed with the description method of the current object. Floating-point objects do not have a description method and cannot be printed. You can format e-f f — object to print
static ALWAYS_INLINE id _class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone, int construct_flags = OBJECT_CONSTRUCT_NONE, bool cxxConstruct = true, size_t *outAllocatedSize = nil) { ASSERT(cls->isRealized()); // Read class's info bits all at once for performance bool hasCxxCtor = cxxConstruct && cls->hasCxxCtor(); bool hasCxxDtor = cls->hasCxxDtor(); bool fast = cls->canAllocNonpointer(); size_t size; size = cls->instanceSize(extraBytes); If (outAllocatedSize) *outAllocatedSize = size; id obj; if (zone) { obj = (id)malloc_zone_calloc((malloc_zone_t *)zone, 1, size); } else { obj = (id)calloc(1, size); } if (slowpath(!) slowpath(!) obj)) { if (construct_flags & OBJECT_CONSTRUCT_CALL_BADALLOC) { return _objc_callBadAllocHandler(cls); } return nil; } if (! zone && fast) { obj->initInstanceIsa(cls, hasCxxDtor); // Core 3: Initialize the pointer, Else {// Use raw pointer isa on the assumption that they might be // doing something weird with the zone or RR. obj->initIsa(cls); // initialize isa pointer and class association} if (fastPath (! hasCxxCtor)) { return obj; } construct_flags |= OBJECT_CONSTRUCT_FREE_ONFAILURE; return object_cxxConstructFromClass(obj, cls, construct_flags); }Copy the code

Summary of alloC process

  • CallAlloc may be optimized out during compiler optimization

For example: the register X0 64 bit, W0 32 bit, store small number of bytes of data, the compiler will optimize the W register

  • CreateInstance -> create memory for isa (class)
  • The alloc process points to _objc_rootAlloc or objc_rootAlloc

  • CallAlloc go twice cause
  • Final conclusion: The program is complete in the LLVM compilation phaseobjc_allocSubstitution of theta, there’s more than substitution hereallocAnd there are many functionsrelease,retain,autoreleaseAs for why we hook these functions, we assume that the system does a lot of monitoring for object creation and release.
  • Process summary:allocAnd so some methods in the compile phaseLLVMtoallocmethodsHook, this function will be replaced byobjc_allocFunction to declare an object at run timeLGPersonAnd to open up memory space for itallocFunction, the first response method isobjc_allocAnd then it will entercallAllocFunction, which never satisfies this criterion the first timefastpath(! cls->ISA()->hasCustomAWZ())Will trigger((id(*)(id, SEL))objc_msgSend)(cls, @selector(alloc))Objc_msgSend Indicates message forwardingLGPersonObject sendsallocNews, this timeallocThe function will actually be called and enter_objc_rootAlloc->callAlloc->_objc_rootAllocWithZone->_class_createInstanceFromZoneThis method does three things:Byte alignment,Open up memory,Binding to an object

init

- (id)init {
    return _objc_rootInit(self);
}
Copy the code
id
_objc_rootInit(id obj)
{
    // In practice, it will be hard to rely on this function.
    // Many classes do not properly chain -init calls.
    return obj;
}
Copy the code
  • The init method returns the object itself
  • Init gives the developer a lot of freedom to customize, to implement a strong override by id, to return the type we need

new

+ (id)new {
    return [callAlloc(self, false/*checkNil*/) init];
}
Copy the code

The source code shows that we go through the callAlloc method flow, and then we go through the init method, so new is alloc + init

conclusion