メッセージメカニズムノート
3171 ワード
この経典の事件から手に入れる
@implementation Son : Father
- (id)init
{
self = [super init];
if (self)
{
NSLog(@"%@", NSStringFromClass([self class]));
NSLog(@"%@", NSStringFromClass([super class]));
}
return self;
}
@end
この答えは何ですか.最初はつぶやいて、息子、老子?しかし、考えてみるとそんなに簡単ではないはずです.確かに、穴ではない問題はありません.まずつぶやいて、答えを見ません.
これはニュースに関する公式解釈です.
When it encounters a method invocation, the compiler might generate a call to any of several functions to perform the actual message dispatch, depending on the receiver, the return value, and the arguments. You can use these functions to dynamically invoke methods from your own plain C code, or to use argument forms not permitted by NSObject’s perform… methods. These functions are declared in/usr/include/objc/objc-runtime.h.
わかりませんが、続けて、ここではObject-cのメッセージメカニズムを明らかにします.メッセージ・メカニズムの最下層を知っています.
OBJC_EXPORT void objc_msgSend(void /* id self, SEL op, ... */ )
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
OBJC_EXPORT void objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... */ )
ここで、[self class]は呼び出されたobjc_であることがわかります.msgSend,[super class]がobjc_を呼び出したmsgSendSuper.もし前がよく見られるなら、どの後ろがいったい何の鬼おじいさんなのか.
まずobjcを見てみましょうsuper
struct objc_super {
id receiver;
Class superClass;
};
receiverは私たちの息子の相手ですが、superClassはあなたが推測した彼の老人です.
しかし[super class]を実行します.概ね内部で実行される論理は、次のとおりです.
私たちの[self class]も同じです.自分でここから探して、それから老人のあれに行って、ずっと上へ行って、仙人のあれまで、最后にすべて仙人のあれで出会った.しかし、私たちのreceiverは息子です.だから彼らは振り回されて、やはり最終的に実行した同じ方法で、同じ受信者です.だから結果は自然に同じで、印刷されたのはすべてSonです.
これを検証するために、次の例を見てください.
@interface GrandFather : NSObject
- (NSString *)name;
@end
@implementation GrandFather
- (NSString *)name {
return [NSString stringWithFormat:@"grandfather:%@",NSStringFromClass([self class])];
}
@end
@interface Father : GrandFather
@end
@implementation Father
- (NSString *)name {
return [NSString stringWithFormat:@"father:%@",NSStringFromClass([self class])];
}
@end
@interface Son : Father
@end
@implementation Son
- (NSString *)name {
return [NSString stringWithFormat:@"son:%@",NSStringFromClass([self class])];
}
- (void)showName {
NSLog([NSString stringWithFormat:@"%@,%@",[self name],[super name]]);
}
@end
もし私がこのように呼び出したら
Son *son = [Son new];
[son showName];
これは結果を見ればわかる.