preface
According to the previous article —-Program loading processGot itdyld
The macro loading process, anddyld
and_objc_init
Docking call relationships. through_dyld_objc_notify_register
Function, I know it’s mainly passing values&map_images
andload_images
: 对map_images
andload_images
Function calls, there is also a simple introduction, so this article, some extension of the previous article.
Resources to prepare
objc
Source 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 loaded
loadAllCategories()
; - Preparation loading method
prepare_load_methods()
; - Call load method
call_load_methods()
;
prepare_load_methods()
So how do we prepare?Preparation process:
- through
for
The cycle, recursively, iscls
And anything not loadedThe parent class
Arrange to load —schedule_class_load()
. - through
for
Circulation, real connection to the outside,cls
Class initializes, allocates read and write data, and returns the real class structure of the classrealizeClassWithoutSwift()
. - through
for
Loop 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 first
load
Write to the table, and then write to the subclassload
—schedule_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 yet
load
Load, 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_categories
inside
When the preparation is loaded, the call is loaded.
call_load_methods()
throughdo-while
Loop, calling the class firstload
And then call the classifiedload
.
call_class_loads()
- Of the class
load
Call: throughloadable_classes
To get insideload
Method and call.
call_category_loads()
- Classification of
load
Call: throughloadable_categories
To get insideload
Method and call.
load
The 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 insideLGGrandSon
This 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 class
implementation
If theDidn't realize
, firstimplement
; - When the class is implemented, determine whether the class is
Initialize the
If 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 directly
callInitialize
Initialization function;
callInitialize()
This function does what:
initialize
Is through theobj_msgSend
Send 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 first
initialize
After calling the subclassinitialize
; - When the classification also has
initialize
, will override that in the classinitialize
; load
First call,initialize
After the call.
initialize
andload
contrast
Initialize and load have essential differences:
load
The function is in the application load phase,dyld
Automatically transferred in the process;initialize
Is triggered when a message is sent to a class.