To begin our question:
@implementation son:father-(ID) init{self = [super init]; if (self) { } return to self;}
This code estimates a lot of people write rotten, even if not write rotten, Xcode automatically generated we also see vomit. Well, to speak of the original,
Come on: This is actually the INIT implementation of calling the parent class before the subclass implements initialization.
It's not the same as saying, it's a blur.
First of all, to understand 1, self is what, super is what. What 2,[Super Init] did. 3, why should self = [super init];
One by one:
What is 1,self and what is super?
> In dynamic methods, self represents an "object"
> In static methods, self stands for "class"
> Original aim, just remember a word: Self represents the caller of the current method
Self and super are the two reserved words that OC provides. But there is a fundamental difference,
Self is a hidden parameter variable of the class, pointing to the object that is currently calling the method (the class is also an object, the class object), and the other hidden parameter is _cmd, which represents the selector of the current class method.
Super is not a hidden parameter, it's just a "compiler indicator"
2, what did [Super Init] Do
When sending a message
Class A
-reposition { ... [Self SetOrigin:someX:someY]; ... }
A a= [A.. init];
[A reposition]; The compiler in the method body will
[Self SetOrigin:someX:someY];
Convert it to
Objc_msgsend (self,_cmd,.. .) 。 self-A
At this point, self refers to the A object, and the method starts looking in a method schedule table corresponding to a class structure, and if it is not found, the inheritance chain is looked for in the parent class.
Similarly, if reposition is a class method, self refers to the class A object.
Class a-reposition { ... [Super SetOrigin:someX:someY]; ... }
[A reposition]; The compiler in the method body will
Convert it to
ID objc_msgsendsuper (struct objc_super *super, SEL op, ...)
The first parameter is a objc_super structure, the second parameter is similar to the selector of the class method above, first look at objc_super what this struct is:
struct Objc_super {
ID receiver;
Class superclass;
};
You can see that this struct contains two members, one is receiver, this is similar to the first parameter receiver of the above Objc_msgsend, the second member is what is the parent class that records the Super class, take the code above as an example, when the compiler encounters A
[Super SetOrigin:someX:someY]
, start doing these things:
> constructs the objc_super structure, at which point the first member variable receiver of this struct is a, which is the same as self. The second member variable, superclass, refers to the superclass of Class A.
> Call the Objc_msgsendsuper method to make this struct and
Setorigin
The SEL passes past. The function inside is doing something like this: from the Superclass method list of the objc_super structure to find Setorigin selector, find and then objc_super->receiver to call this selector, The Objc_msgsend function may also be used, but the first parameter thereceiver is Objc_super->receiver, and the second argument is found from Objc_super->superclass Selector
3, why should self = [super init];
is mainly the problem of class inheritance. A subclass inherits from the parent class and obtains the related properties and methods, so in the initialization method of the subclass, the initialization method of the parent class must first be called to implement the initialization of the parent class related resources.
The role of [Super Init]:
The object-oriented embodiment, first using the parent class Init method for the child class instance of the parent part of the property initialization.
Calling [Super init] may alloc fail, so let's judge self! =nil to decide whether to perform the following initialization operation if the creation of a nil instance fails, terminating the statement execution within if.
In Swift, the user is no longer allowed to actively invoke Init to complete the creation and initialization of an object, which is accomplished by the Init constructor. There is also a similar concept of a "possibly failed constructor" in Swift.
Here's a look at this:
@implementation son:father-(ID) init{self = [super init]; if (self) { NSLog (@ '%@ ', Nsstringfromclass ([Self class])); NSLog (@ "%@", Nsstringfromclass ([Super Class]); } return self;} @end
It should not be difficult to analyze the printed result:
Son
Son
When sending a class message, whether self or super, the message body remains self , meaning that self and super point to the same object. Just find the location difference of the method, one from this class, and one from the superclass of this class.
In general, the class method is defined only in the root class NSObject, and very few subclasses rewrite the class method.
So [Slef class] and [Super class] Both find the method implementation in the root class, and the message receiving body is both a
If the override may be different.
Naturally all print out
In an example:
#import <Foundation/Foundation.h> @interface enginesuper:nsobject-(void) printcurrentclass; @end #import " EngineSuper.h "@implementation enginesuper-(void) printcurrentclass{ NSLog (@" =enginesuper=======%@ ", [Self Class]);} @end @interface engine:enginesuper-(void) printsupclass; @end @implementation engine-(void) printsupclass{ [Super Printcurrentclass];} Call: Engine *engine = [[Engine alloc]init]; [Engine printcurrentclass];//calls the parent class method directly, the engine does not reload it [engine printsupclass];//indirectly calls the parent class method,
Printing is of course:
Engine
Engine
The self in the method body always refers to the recipient of the method and the object engine. ,
Change to NSLog (@ "=enginesuper=======%@", [Super class]), and the result is the same.
Super is a fake hair, compiler symbol, it can be replaced by [Slef class], but the method is to start from the Super class self to find.
OC Self and Super