Topic
On the topic, known A is Grandpa, B is Father, C is grandson.
@interface a:nsobject-(void) F; @end @interface b:a-(void) F; -(void) g; @end @interface c:b-(void) F; @end
A,b,c each implement the function F, only B implements the function G.
@implementationA- (void) f{NSLog (@"A");}@end@implementationB- (void) f{NSLog (@"B");}- (void) g{[self f]; [Super F]; NSLog (@"%@", [Selfclass]); NSLog (@"%@", [Superclass]);}@end@implementationC- (void) f{NSLog (@"C");}@end
Excuse me, what does the following code output?
c *c = [[C Alloc] init];[ C G];
The answer is CACC.
Analysis
There is no g in 1.C, why can I call the method of B
C is inherited from B, so C, although there is no G method, but will go from the bottom up, looking for a class B to hit the G method to call.
2. About [self f]
In the process of calling G of B, self actually C, because at this time the recipient of the function G message is C. So the system starts from the bottom up from the self class (that is, c) , because F is implemented in C, so the direct output is C.
3. About [Super F]
This question is the most puzzling to me, the crouching trough, incredibly output is a rather than b?!
The first thing to make clear is that self and super are not on the same level.
What is self?
Self is a hidden argument to the class that points to the currently called method's class, and another hidden parameter is _cmd, which represents the selector of the current class method.
What is super?
Super is not an imaginary self.superclass.
Super is a objective-c syntax sugar, is a compiler indicator, like a macro, run-time Xcode does not know super this thing.
In fact, the essence of Objective-c's function call is
ID objc_msgsend (ID thereceiver, SEL op, ...)
ellipses indicate indeterminate parameters.
The essence of [self f] is objc_msgsend (self, F, "");
So, this is different from C + +, not self to call the function F, but the message F sent to Self,self is the message recipient. It is because of this that the objective-c [nil F] is not a problem, because any message sent to nil returns nil.
Objc_msgsend (Thereceiver, op, ...) The essence is, starting from the class where Thereceiver is located, constantly looking up, to see which class implements the OP, and once found, sends the message to it for processing.
But [Super F] is not the case,[Super F] is essentially
ID objc_msgsendsuper (struct objc_super *super, SEL op, ...)
ellipses indicate indeterminate parameters.
The essence of [self f] is objc_msgsendsuper (super, F, "");
Who is Objc_super?
struct objc_super { ID receiver; __unsafe_unretained Class Super_class;};
What is receiver of Objc_super?
Reveiver is the recipient of the current message, and the code is written in [C G], so the super Receiver is C. You can also understand that it is self.
What is the super_class of Objc_super?
Super_class is the parent class of the current Super code class, it is very round, but this sentence must be well understood. For example, whoever calls G, C or B, the Super Super_class in G [Super F] must be a, because the Super 5 letters are written in B.
Objc_msgsendsuper (Super, OP, ...) The essence is, starting from the class where the Super_class->super_class is located, constantly looking up, see which class implemented the OP, once found the message is sent to it processing.
At compile time, the compiler sees super and constructs a struct. Objc_super->receiver filled out c,objc_super->super_class filled in a. So the runtime compiler is not aware of super.
If you already know the logic above, please look back [super F].
[Super F],super->reveiver is C,super->super_class is a. So I looked for f from a, and the system could call it that way.
Objc_msgsend (Super->recevier, F, nil)//At this time F is the F that has been found, i.e. the f of a
4. About [Self class]
First, it is necessary to look at the implementation of the class, referring to the Apple runtime Open source code
-(Class)class { return object_getclass (self);}
You can see the class name returned by class as self.
OK, continue, [Self class], class is also a message, the recipient is self, that is, C, so the system from C began to find the implementation of class function, did not find, find B, find a can not find, to the Nsobjcect this layer found.
At this point the class method of NSObject is called, and when Self is C, then C is returned.
5. About [Super class]
This question seems strange at first, and it's not scientific that [self class] and [super class] Output the same thing. But it is not surprising that the above knowledge has been understood.
When you execute [super class], the compiler replaces [super class] with the
Objc_msgsendsuper (Super, class, nil)
Where super is reveiver=c,superclass=a.
The system from a start to find class, can not find, to the NSObject this layer found.
Then the system might call
Objc_msgsend (Objc_super->receiver, class, nil)//This time class is the class that has been found, that is, the class of NSObject
At this point the class method of NSObject is called, and when Self is C, then C is returned.
Summarize
After the reason understood is the efficiency of the question of thinking, all self is from the message recipients of the class start from the bottom of the search;
Reference links
"Inquisitive objective-c Runtime (1)-Self & Super"
"Self and Super in Objective-c"
"Apple Runtime open source code"
The understanding of the OBJECTIVE-C super
Objective-c Self Super