Ios – Class loading process (DyLD loading process)

Preface:

The previous article analyzed the app startup process and mentioned that _objc_init is called during dyLD loading. In this article we’ll take a closer look at what the _objc_init method does.

Explore _objc_init

Open the objC source global search _objc_init method

_objc_init() init() init();

environ_init()

Such as:

Remove lines 426-430 and delete the useless judgment, as shown below

We’ve used some of these environments before, so let’s look at themOBJC_DISABLE_NONPOINTER_ISA, we do as follows

Let’s run the code and print the Person

Remove the set

In common Settings for example:

  • DYLD_PRINT_STATISTICS: If DYLD_PRINT_STATISTICS is set to YES, the console will print the loading time of the App, including the overall loading time and the dynamic library loading time, that is, the startup time before main (check the pre-main time).

  • NSDoubleLocalizedStrings: Working with internationalization and localization can be a time-consuming task. If you want to test the internationalization of the translated language UI, you can specify this startup item. You can set NSDoubleLocalizedStrings to YES.

  • OBJC_PRINT_LOAD_METHODS: Displays the call information of the + (void)load method of Class and Category

, etc.

tls_init()

Thread key binding

static_init()

Mainly runs system-level C++ static constructors indyldBefore calling our static constructor,libccall_objc_initMethods, i.e.,System-level C++ constructors run before custom C++ constructors

runtime_init()

mainlyThe runtimeInitialization is divided into two parts:Class initialization,Class to initialize the table

exception_init()

It is mainly to initialize libobJC’s exception processing system, register the callback of the exception processing, so as to monitor the exception processing, the source code is as follows

Look at the **_objc_terminate** function

Enter the **uncaught_handler** method

Uncaught_handler is an instance of objC_uncaught_Exception_handler. The default value is _objC_default_uncaught_Exception_handler

Search ** objc_uncaught_EXCEPtion_handler ** function implementation

Exceptions fall into three categories

  • Mach exceptions: These are the lowest level kernel-level exceptions. User developers can catch Mach exceptions by setting exception ports for Thread, task, and host directly through the Mach API.

  • Unix signals: Also known as BSD signals, if the developer does not catch a Mach exception, the exception is converted to the corresponding Unix signal by the host layer method ux_Exception () and sent to the error thread via the threadSignal () method. Single can be caught using the method Signal (x, SignalHandler).

  • NSException Application-level exception: It is an uncaught Objective-C exception that causes the program to send itself a SIGABRT signal and crash. For an uncaught Objective-C exception, you can catch it with a try catch. To capture or through NSSetUncaughtExceptionHandler () mechanism.

Aiming at application level anomalies, can by registering exception handling function, namely NSSetUncaughtExceptionHandler mechanism to realize thread to keep alive, collect upload crash logs, so in development for crash to intercept processing, NSSetUncaughtExceptionHandler in the app code into a function to the system, when an exception occurs, call a function to upload crash logs and then return to the original app layer is unusual, nature is the functional programming ideas, a callback function to the app

As shown in the figure below

KC open class content, can be a custom function to replace the ExceptionHandler to collect application level exceptions

cache_init()

Cache initialization, source code as follows

_imp_implementationWithBlock_init()

This method basically starts the callback mechanism, which usually doesn’t do much because all initialization is lazy, but for some processes we can’t wait to load libobjc-trampolines.dylib, whose source code is as follows

Core:

_dyld_objc_notify_register(&map_images, load_images, unmap_image);

The concrete implementation of this method is inarticleThe source code implementation is described in detaildyldIn the source code, the following_dyld_objc_notify_registerMethod declaration

Description:

  • Used by objC runtime only

  • Registers handlers to be called when objC images are mapped, unmapped, and initialized

  • Dyld will call the mapped function through an array containing objC-image-info’s image file

The meanings of the three parameters in the method are as follows:

  • Map_images: This function is triggered when dyld loads an image into memory

  • Load_image: this function is triggered when dyld initializes the image

  • Unmap_image: Triggered when dyld removes the image

The specific analysis process has been explained in detail in the previous article

Note: dyld’s association with Objc

  • sNotifyObjCMapped == mapped == map_images

  • sNotifyObjCInit == init == load_images

  • sNotifyObjCUnmapped == unmapped == unmap_image

The association between DYLD and Objc is shown in the following figure:

Map_images call timing

Take a look at the map_images implementation

Enter the map_images_NOLock function

Go to the _read_images method (core method, remember this method carefully)

The method is long, and the next article will examine it in detail (lazy-loaded and non-lazy-loaded classes).

The appendix

Summary of environment variables

Environment variable name instructions
OBJC_PRINT_OPTIONS Prints OBJC’s set options
**OBJC_PRINT_IMAGES** The loaded image information is displayed
**OBJC_PRINT_LOAD_METHODS** Prints calls to the + (void)load methods of Class and Category
**OBJC_PRINT_INITIALIZE_METHODS** Print the call information for Class + (void)initialize
**OBJC_PRINT_RESOLVED_METHODS** Print class methods generated by +resolveClassMethod: or +resolveInstanceMethod:
OBJC_PRINT_CLASS_SETUP Print the Class and Category Settings
OBJC_PRINT_PROTOCOL_SETUP Prints the Protocol setting process
OBJC_PRINT_IVAR_SETUP The Ivar setup process is displayed
OBJC_PRINT_VTABLE_SETUP Print the vtable setting process
OBJC_PRINT_VTABLE_IMAGES Print the method of overwriting vtable
OBJC_PRINT_CACHE_SETUP Print the procedure for setting up the method cache
OBJC_PRINT_FUTURE_CLASSES Print classes that will be used for seamless conversion from CFType to NSObject (such as CFArrayRef to NSArray *)
OBJC_PRINT_GC Print some garbage collection operations
OBJC_PRINT_PREOPTIMIZATION Print the greeting before dyLD shared cache optimization
OBJC_PRINT_CXX_CTORS Print the construction and destructor calls of C++ objects in class instances
**OBJC_PRINT_EXCEPTIONS** Printing exception Processing
**OBJC_PRINT_EXCEPTION_THROW** Prints Backtrace for all exceptions thrown
OBJC_PRINT_ALT_HANDLERS Abnormal processing of Alt operations
**OBJC_PRINT_REPLACED_METHODS** Print the method to be replaced by Category
**OBJC_PRINT_DEPRECATION_WARNINGS** Prints all obsolete method calls
OBJC_PRINT_POOL_HIGHWATER Prints autoreleasepool high watermark warnings
OBJC_PRINT_CUSTOM_RR Prints a class with a custom retain/release method that is not optimized
OBJC_PRINT_CUSTOM_AWZ Prints a class with a custom allocWithZone method that is not optimized
OBJC_PRINT_RAW_ISA Print the classes that need access to the original ISA pointer
OBJC_DEBUG_UNLOAD Prints a warning when uninstalling misbehaving bundles
OBJC_DEBUG_FRAGILE_SUPERCLASSES Prints a warning when a subclass may be broken by changes to its parent class
OBJC_DEBUG_FINALIZERS Warning implements -dealloc but not -Finalize classes
OBJC_DEBUG_NIL_SYNC Warning of @synchronized(nil) calls that do not lock
OBJC_DEBUG_NONFRAGILE_IVARS Prints the behavior of suddenly rearranging non-fragile ivars
OBJC_DEBUG_ALT_HANDLERS Record more Alt operation errors
OBJC_DEBUG_MISSING_POOLS Warning: Using autoRelease without a pool may leak memory
OBJC_DEBUG_DUPLICATE_CLASSES Stop when a class duplication occurs
OBJC_USE_INTERNAL_ZONE Allocate runtime data in a dedicated MALloc area
OBJC_DISABLE_GC Forcibly turn off automatic garbage collection, even if the executable requires garbage collection
OBJC_DISABLE_VTABLES Disable VTable distribution
OBJC_DISABLE_PREOPTIMIZATION Disable the greeting before dyLD shared cache optimization
OBJC_DISABLE_TAGGED_POINTERS Disable tagged Pointer optimization for NSNumber
**OBJC_DISABLE_NONPOINTER_ISA** Close access to the non-pointer ISA field! [](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e04ca377832e4986a3ee555465ced054~tplv-k3u1fbpfcp-watermark.image)! [](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4f5e880bb2724113ba75acda29af7b53~tplv-k3u1fbpfcp-watermark.image)