preface

According to the previous article —-Program loading processGot itdyldThe macro loading process, anddyldand_objc_initDocking call relationships. through_dyld_objc_notify_registerFunction, I know it’s mainly passing values&map_imagesandload_images:map_imagesandload_imagesFunction calls, there is also a simple introduction, so this article, some extension of the previous article.

Resources to prepare

  • objcSource code download address:Multiple versions of ObjC

To enter the body

load_images()

load_images()The function does this:

  • Determines whether categories are loaded, and if not, all categories are loadedloadAllCategories();
  • Preparation loading methodprepare_load_methods();
  • Call load methodcall_load_methods();

prepare_load_methods()

So how do we prepare?Preparation process:

  • throughforThe cycle, recursively, isclsAnd anything not loadedThe parent classArrange to load —schedule_class_load().
  • throughforCirculation, real connection to the outside,clsClass initializes, allocates read and write data, and returns the real class structure of the classrealizeClassWithoutSwift().
  • throughforLoop to add the category to the loadable listadd_category_to_loadable_list();

schedule_class_load()

From this source block, you can see:

  • So by recursion, let’s take the parent firstloadWrite to the table, and then write to the subclassloadschedule_class_load();
  • Add a class to the loadable list —add_class_to_loadable_list();

add_class_to_loadable_list()

From this source block, you can see:

  • If the superclass and subclass haven’t done yetloadLoad, return directly, continue recursive loading;
  • If there is no load method, implement a load method and reload;
  • Add the class to the loadable list —loadable_classes;

add_category_to_loadable_list()

Classifications are treated in much the same way as classes. Finally, the category is addedloadable_categoriesinside

When the preparation is loaded, the call is loaded.

call_load_methods()

throughdo-whileLoop, calling the class firstloadAnd then call the classifiedload.

call_class_loads()

  • Of the classloadCall: throughloadable_classesTo get insideloadMethod and call.

call_category_loads()

  • Classification ofloadCall: throughloadable_categoriesTo get insideloadMethod and call.

loadThe function summary

According to the above analysis, when executing load_images, the load of the class is first written to loadable_classes, and then the load of the category is written to loadable_categories. Calls are made to load classes from loadable_classes, and to load classes from loadable_categories.

You can do another example: create LGPerson from NSObject, LGSon from LGPerson, LGGrandSon from LGSon, and call them in their.m files

+ (void)load{
    NSLog(@"%s", __func__);
}
Copy the code

Finally, inmain()Init insideLGGrandSonThis class:So that confirms our analysis.

When it comes to load, the initialize function immediately comes to mind. This is often asked in an interview. Next, initialize is analyzed and compared to the load function.

initialize()

According to the message lookup process, we know that in the message slow lookuplookUpImpOrForward(), there are implementations of classesrealizeAndInitializeIfNeeded_locked(), as shown below:

realizeAndInitializeIfNeeded_locked()

fromrealizeAndInitializeIfNeeded_locked()In function analysis, the class must be implemented first, that is, carried out firstload()Before you caninitialize()Initialize, as shown below:This function does what:

  • Determine whether a classimplementationIf theDidn't realize, firstimplement;
  • When the class is implemented, determine whether the class isInitialize theIf theNo initialization,Initialize.

initializeAndMaybeRelock()

This function does what:

  • Check whether the class has been initialized, and if so, return directly;
  • Detect whether non-metaclasses are implemented, if not, it needs to be implemented;
  • Initialize non-metaclasses.

initializeNonMetaClass()

This function does what:

  • Recursive initialization, starting from the parent class —-initializeNonMetaClass();
  • When initialization is performed, call directlycallInitializeInitialization function;

callInitialize()

This function does what:

  • initializeIs through theobj_msgSendSend a message, so it is called: send a message;

Using the previous example, in the.m files of LGPerson, LGSon and LGGrandSon, I added:

+ (void)initialize
{
    NSLog(@"%s", __func__);
}
Copy the code

Then run the project:According to the printed results, it can be known that:

  • Call the parent class firstinitializeAfter calling the subclassinitialize;
  • When the classification also hasinitialize, will override that in the classinitialize;
  • loadFirst call,initializeAfter the call.

initializeandloadcontrast

Initialize and load have essential differences:

  • loadThe function is in the application load phase,dyldAutomatically transferred in the process;
  • initializeIs triggered when a message is sent to a class.