Summary of basic principles of iOS

The main goal of this article is to understand how dyLD relates to OBJC

In the dyLD loading process of the last article, we combed out the loading process of DYLD. The association between DYLD and OBJC will be introduced in detail below

_objc_init Source code parsing

First, take a look at the source of the _objc_init method in libObjc

According to the source code, it is mainly divided into the following parts:

  • environ_init: initializes a set of environment variables and reads theThe environment variable
  • tls_init: aboutthreadThe key of the binding
  • static_init: runs C++ static constructors (only system level constructors are run), indyldBefore calling the static destructor,libcWill be called_objc_init
  • runtime_init: Runtime initializes the runtime environmentunattachedCategories,allocatedClasses(Table initialization)
  • exception_initInitialization:libObjcException handling system
  • cache_init: Cache Initializes the cache
  • _imp_implementationWithBlock_initStart the callback mechanism. Normally this doesn’t do much because all initialization is lazy, but for some processes we can’t wait to load trampolines dylib
  • _dyld_objc_notify_register: DyLD registration

The following is mainly for the above parts with the source code

1. Environ_init method: initialize environment variables

The source code for the environ_init method is shown below, with the key code being the for loop

There are two ways to print all environment variables

  • Separate out the for loop, remove all conditions, and print the environment variables

Run the export OBJC_HELP=1 command to print environment variables

These Environment Variables can be configured using target — Edit Scheme — Run –Arguments — Environment Variables. :

  • DYLD_PRINT_STATISTICSSet:DYLD_PRINT_STATISTICS 为YES, the console will print the loading time of App, including the overall loading time and the dynamic library loading time, i.eStart time before main (check pre-main time), you can learn about the time consuming part by setting itStart the optimization.
  • OBJC_DISABLE_NONPOINTER_ISA: Eliminate the generation of correspondingnonpointer isaNonpointer ISA Pointer addressAt the end of 1), all generated are ordinary isAs
  • OBJC_PRINT_LOAD_METHODS: printingClass 及 Category 的 + (void)loadMethod call information
  • NSDoubleLocalizedStrings: Internationalization and localization of the project can be a time-consuming task, so if you want to test the internationalization of the translated language UI, you can specify this initiator item. You can set theNSDoubleLocalizedStringsforYES.
  • NSShowNonLocalizedStrings: Once in a while, when you’re doing internationalizationThe string is not localized“Can be setNSShowNonLocalizedStrings 为YESAll,Strings that are not localized are all capitalized.

Environment variable – OBJC_DISABLE_NONPOINTER_ISA

For example, set OBJC_DISABLE_NONPOINTER_ISA to YES, as shown in the following figure

Before OBJC_DISABLE_NONPOINTER_ISA is not set, the isa address is printed in binary format and ends with 1

After setting the OBJC_DISABLE_NONPOINTER_ISA environment variable, the end becomes 0

So OBJC_DISABLE_NONPOINTER_ISA can control the ISA optimization switch to optimize the entire memory structure

Environment variables – OBJC_PRINT_LOAD_METHODS

  • configurationPrint the loadMethod environment variablesOBJC_PRINT_LOAD_METHODS, is set toYES
  • inLGPersonClass to rewrite+ the load function, run the program, the load function is printed as follows