write in front
It took some time in recent days to get to know something about the OBJECTIVE-C runtime, which involved the +load approach, such as method swizzling, which is usually done in the +load method of the category. Before the use of initializer and load is more doubtful, but has not been detailed to understand, taking this as an opportunity to set all the resources, analyze it!
Regarding understanding +initialize
and +load
, personal feeling reference Official document "NSObject Class Reference" is enough.
+initialize
About the +initialize
method, "NSObject Class Reference" is described as follows:
Initializes the class before it receives its first message.
It can be understood +initialize的
to create the right environment for the class before it is used;
For its use, the NSObject Class Reference is described below:
The runtime sends initialize to each class in a program just before the class, or any class that inherits from it, is sent Its first message is from within the program. The runtime sends the initialize message to classes in a thread-safe manner. Superclasses receive this message before their subclasses. The superclass implementation may is called multiple times if subclasses do not implement Initialize-the runtime would call The inherited implementation-or if subclasses explicitly call [Super Initialize].
In this paragraph, we can draw the following meanings:
+initialize
The method is called at runtime;
- For a class, its class
+initialize
method is called before the object accepts any messages;
- If the +initialize method of the parent class and the subclass is called, the call of the parent class must precede the subclass, which is automatically done by the system, and there is no need for explicit invocation in subclass +initialize
[super initialize];
;
- The runtime system handles +initialize messages in a thread-safe manner, so it is not necessary to use thread-safety tools such as lock, mutex in +initialize to ensure thread safety;
- The +initialize method of a class is not necessarily called only once, at least two cases are called multiple times:
- Explicit invocation of subclasses
[super initialize];
;
- Subclasses do not implement the +initialize method;
The following example shows the behavior of a class that has +initialize
been executed more than once.
Defines three classes: person, Student, teacher,student, and Teacher inherit from NSObject from Person,person. Both the person and the student implement the +initialize
method, teacher does not implement the method, as follows:
The implementation of the person's +initialize Method + (void) Initialize { NSLog (@ "person initialize");}//Student implementation of the +initialize method + (void) Initialize { NSLog (@ "Student initialize");}
The following results are performed:
-(void) viewdidload { Student *astudent = [[Student alloc] init]; Teacher *ateacher = [[Teacher alloc] init]; [Super Viewdidload];} /* Output: Person initializestudent Initializeperson initialize*/
As you can see, for student, +initialize
its Super Class (person) method is first called before its method is called, and +initialize
for teacher, there is no method defined, +initialize
so it calls super directly. Class (Person) +initialize
method, which causes the method of person to +initialize
be executed two times.
Is there a way to avoid a person's +initialize
method being called multiple times? Of course:
The implementation of the person's +initialize Method + (void) Initialize { static BOOL B = false; if (!b) { NSLog (@ "person initialize"); b = true;} }
You can also do this:
The implementation of the person's +initialize Method + (void) Initialize { if (self = = [Person class]) { NSLog (@ ' person initialize '); }}
NSObject Class Reference also +initialize
warns about the use of methods:
Because Initialize is called in a thread-safe manner and the order of initialize being called on different classes are not Guaranteed, it's important to does the minimum amount of work necessary in initialize methods. Specifically, any code this takes locks that might being required by other classes in their initialize methods are liable to L EAD to deadlocks. Therefore should not rely on initialize for complex initialization, and should instead limit it to straightforward, CL The local initialization.
To summarize, this is the case:
- Do not
+initialize
handle complex logic in;
So what can +initialize do about it? You can do some simple initialization work, for example, for an object that inherits from Uicollectionviewcell's custom class Photoviewcell,photoviewcell might have some common resources, such as a label Color,label Font and so on, there's no need to create these exact same resources in the-initxxoo method, which can be done in +initialize in Photoviewcell, as follows:
+ (void) Initialize { Titlefont = [Uifont systemfontofsize:12]; Titleheight = 20.0f; Videoicon = [UIImage imagenamed:@ "Ctassetspickervideo"]; Titlecolor = [Uicolor whitecolor]; Checkedicon = [UIImage imagenamed:@ "ctassetspickerchecked"]; Selectedcolor = [Uicolor colorwithwhite:1 alpha:0.3];}
+initialize
After all, it brings a surprising amount of information, rather disappointing.
+load
Both are executed once (the system is called at most once, regardless of the developer's active use);
Load is executed when the class is loaded into the system;
If both the parent and child classes are called, the invocation of the parent class must precede the child class
To create the right run environment in advance of the application run
Do not rely heavily on these two methods when you use them, unless you really need to
About the +load
method, "NSObject Class Reference" is described as follows:
Invoked whenever a class or category is added to the OBJECTIVE-C runtime; Implement this method to perform class-specific behavior upon loading.
For its use, the NSObject Class Reference is described below:
The load message is sent to classes and categories this is both dynamically loaded and statically linked , but only if the newly loaded class or category implements a method can respond.
The order of initialization is as follows:
- All initializers on any framework of you link to.
- all +load methods in your image.
- all C + + static initializers and c/c++ attribute (constructor) functions in your image.
- all initializers in frameworks so link to you.
In addition:
- A class ' s +load method was called after all of its superclasses ' +loa D methods.
- A Category +load method is called after the class ' s own +load method.
in a custom implementation of load you can therefore safely message other unrelated classes from the same image, but a NY load methods implemented by those classes and not having run yet.
From this text you can read the following information:
- Before a program (main function) is run, the libraries used are loaded into the runtime, and the methods of the classes and categories added to the runtime system
+load
are called; (this is easy to verify by printing statements);
- If the +load method of the parent class and the subclass is called, the call of the parent class must precede the subclass, which is automatically done by the system, and there is no need for explicit invocation in subclass +load
[super load];
;
- The document does not state whether the execution of +load is thread-safe, but considering that it was called before runtime, so it is not necessary to talk about whether it is thread-safe, according to my understanding, multithreading in the runtime only talk about meaning;
- If a class consists of a main class and multiple categories, it allows the main class and category to have their own +load method, except that the +load in the category is executed after the +load of the main class;
About +load
the use of the scene, I know that at least one, method swizzling processing is generally done in the category +load
, refer to here.
Reference
- "NSObject Class Reference";
+initialize and +load in the Objective-c