消息機制筆記

從這個經(jīng)典的案列入手


@implementation Son : Father
- (id)init
{
    self = [super init];
    if (self)
    {
        NSLog(@"%@", NSStringFromClass([self class]));
        NSLog(@"%@", NSStringFromClass([super class]));
    }
    return self;
}
@end

這個答案是什么呢。開始的時候嘀咕,兒子,老子?但想想應(yīng)該不是這么簡單,誠然,確實沒有不是坑的題,先嘀咕著,不看答案。

這是關(guān)于消息的官方解釋

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.

  1. objc_msgSend sends a message with a simple return value to an instance of a class.
  2. objc_msgSend_stret sends a message with a data-structure return value to an instance of a class.
  3. objc_msgSendSuper sends a message with a simple return value to the superclass of an instance of a class.
  4. objc_msgSendSuper_stret sends a message with a data-structure return value to the superclass of an instance of a class.

看不懂,繼續(xù)往下,這里就要清楚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]是調(diào)用的objc_msgSend,而[super class]調(diào)用的是objc_msgSendSuper。如果前面的很常見,哪后面的到底是個什么鬼大爺。

我們先看看objc_super

struct objc_super {
    id receiver;
   Class superClass;
};


receiver還是我們的兒子對象,而superClass就是你猜的他老漢。

但我們執(zhí)行[super class]。大概內(nèi)部執(zhí)行的邏輯是:

  1. 首先去老漢那去找這個方法。是否存在,如果不存在就繼續(xù)讓上找。
  2. 在這里,我們都沒有去實現(xiàn)這個class,所以找來找去在仙人那NSObject那找到了。

而我們的[self class]也是一樣的。從自己這開始找,然后去老漢那,一直往上,直到仙人那,最后都在仙人那相遇了。但我們的receiver都是兒子。所以他們折騰來回,還是最終執(zhí)行的同一個方法,同一個接受者。所以結(jié)果自然也一樣,打印出來都是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

如果我這樣調(diào)用

Son *son = [Son new];
[son showName];

這個看下結(jié)果就明了。

總結(jié)下,第一個參數(shù)只是告訴引擎從那個層級上開始找這個SEL,直到找到這個。而我們隱藏的第一個參數(shù)才是真正的Receiver。他才是真正的施法者。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • **2014真題Directions:Read the following text. Choose the be...
    又是夜半驚坐起閱讀 9,941評論 0 23
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,789評論 0 9
  • “行業(yè)分析是商業(yè)思考的基石。”---可能是高爾基說的。 公司制定戰(zhàn)略、進行咨詢項目、做市場調(diào)研、創(chuàng)立公司或者投資人...
    飛行公路閱讀 681評論 0 14
  • 家庭會議一如既往無聊 從昨天10點多到今天凌晨 我假裝投入 我知道你們付出很多 但請原諒我的自私 我想要獨立的自我...
    角落蜷縮閱讀 195評論 0 0