Alloc analysis of NSObject


This chapter explores NSObject alloc source code. NSObject = [NSObject alloc]; NSObject *objc = [NSObject alloc]; This line of code does not go directly into the alloc method, which is different from the custom alloc class flow we explored earlier, right? So what’s the difference between an NSObject alloc and a custom class alloc?


0x00 — objc_alloc

At the breakpoint, go to Debug –> Debug Workflow –> Always Show Disassembly;

Learned from assembly debugging:

  • NSObjecttheallocBefore callingobjc_alloc, custom classTestIt’s also called firstobjc_alloc;

System level initialization of NSObject is done, so NSObject’s alloc is called:

alloc --> objc_alloc --> calloc --> _objc_rootAllocWithZone

The calling relationship of a custom class is:

alloc --> objc_alloc --> calloc --> objc_msgSend(cls,alloc) --> alloc -- > calloc --> _objc_rootAllocWithZone


0x01 — Analyze custom class calls two timesalloc

First of all, why does a custom class call to alloc go directly into an objc_alloc method?

The reason, based on the particularity of alloc, should be that the LLVM compiler helped us make the function pointer jump, so find a copy of Apple’s open source LLVM-Project and see if there are any clues 👩❤️👩

  1. searchobjc_allocFind the current file as shown below by manyobjc_allocKey words; Stroke it down bit by bit;

  1. Further down,shouldUseRuntimeFunctionForCombinedAllocInitThis method represents version control;

  1. Then find out where version control is used. Find special messages to sendtryEmitSpecializedAllocInit

  1. When encountering the key code that is not easy to find, turn on God vision and search the keyword currentlyomf-aloc

Below will invoke this method special messages tryGenerateSpecializedMessageSend objc_alloc will call for the first time, and conditions are not set up, walk GenerateMessageSend common message is sent, went to the alloc process; So

The process of custom class alloc will go two times, the first time to send alloc will go to objC_alloc, through objC_alloc will go to callAlloc message sending, will go to alloc source code again;

CodeGen::RValue CGObjCRuntime::GeneratePossiblySpecializedMessageSend(
    CodeGenFunction &CGF, ReturnValueSlot Return, QualType ResultType,
    Selector Sel, llvm::Value *Receiver, const CallArgList &Args,
    const ObjCInterfaceDecl *OID, const ObjCMethodDecl *Method,
    bool isClassMessage) {
  if (Optional<llvm::Value *> SpecializedResult =
          tryGenerateSpecializedMessageSend(CGF, ResultType, Receiver, Args,
                                            Sel, Method, isClassMessage)) {
    return RValue::get(SpecializedResult.getValue());
  }
  return GenerateMessageSend(CGF, Return, ResultType, Sel, Receiver, Args, OID,
                             Method);
}
Copy the code

This code is to explain why two times alloc, tryGenerateSpecializedMessageSend this function in the if condition is bound to go, from the top, there are a case in this function, if the alloc, invoked objc_alloc, Then if this condition is not true, the following GenerateMessageSend function is executed, and the normal message is sent, going through the alloc process.


0x02 — Attached flow chart

  • NSObject allocThe flow chart

  • Custom classallocThe flow chart