iOS底層原理之消息發(fā)送

OC中的方法調(diào)用,其實(shí)都是轉(zhuǎn)化為objc_msgSend函數(shù)的調(diào)用,objc_mesgSend的執(zhí)行流程可分為3個(gè)階段

  • 消息發(fā)送
  • 動(dòng)態(tài)方法解析
  • 消息轉(zhuǎn)發(fā)

消息轉(zhuǎn)發(fā)

消息轉(zhuǎn)發(fā)的流程圖

動(dòng)態(tài)方法解析

動(dòng)態(tài)方法解析

開發(fā)者可以實(shí)現(xiàn)以下的辦法來實(shí)現(xiàn)動(dòng)態(tài)添加方法實(shí)現(xiàn)

  • +resolveInstanceMethod:
  • +resolveClassMethod:

動(dòng)態(tài)解析后會(huì)重新走消息發(fā)送的流程,從receiveClasscache中查找方法這一步開始執(zhí)行

創(chuàng)建一個(gè)Person類,然后在.h文件中寫一個(gè)- (void)test,但是不寫具體實(shí)現(xiàn),然后調(diào)用.會(huì)打印出最常見的unrecognized selector sent to instance.

- (void)other{
NSLog(@"%s",__func__);
}
+ (BOOL)resolveInstanceMethod:(SEL)sel{
if (sel == @selector(test)) {
//獲取其他方法
Method method = class_getInstanceMethod(self, @selector(other));
//動(dòng)態(tài)添加test的方法
class_addMethod(self, sel, method_getImplementation(method), method_getTypeEncoding(method));
return YES;
}
return [super resolveInstanceMethod:sel];
}

消息轉(zhuǎn)發(fā)

如果一個(gè)方法在消息發(fā)送階段沒有找到相關(guān)方法,也沒有進(jìn)行動(dòng)態(tài)方法解析,這個(gè)時(shí)候就會(huì)走到消息轉(zhuǎn)發(fā)階段了.

消息轉(zhuǎn)發(fā)

forwardingTargetForSelector

創(chuàng)建兩個(gè)類Person和Student,在Person.h里面寫一個(gè)實(shí)例方法,但是不去實(shí)現(xiàn)相關(guān)方法继谚。

在Person里面實(shí)現(xiàn)這個(gè)方法
- (id)forwardingTargetForSelector:(SEL)aSelector {
    if (aSelector == @selector(test)) {
        return [[Student alloc]init];
    }
    return nil;
}

調(diào)用forwardingTargetForSelector,返回值不為nil時(shí)深啤,會(huì)調(diào)用objc_msgSend(返回值, SEL)晃琳,結(jié)果就是調(diào)用了objc_msgSend(Student,test)

methodSignatureForSelector(方法簽名)

當(dāng)forwardingTargetForSelector返回值為nil,或者都沒有調(diào)用該方法的時(shí)候,系統(tǒng)會(huì)調(diào)用methodSignatureForSelector方法厦滤。調(diào)用methodSignatureForSelector,返回值不為nil,調(diào)用forwardInvocation:方法;返回值為nil時(shí),調(diào)用doesNotRecognizeSelector:方法

對(duì)于方法簽名的生成方式

  • [NSMethodSignature signatureWithObjCTypes:"i@:i"]
  • [[[Student alloc]init] methodSignatureForSelector:aSelector];
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    if (aSelector == @selector(test)) {
        return [[[Student alloc]init]methodSignatureForSelector:aSelector];
       // return [NSMethodSignature signatureWithObjCTypes:"i@:i"];
    }
    return [super methodSignatureForSelector:aSelector];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation {
    NSLog(@"=======");
}

NSInvocation中封裝了一個(gè)方法調(diào)用,包括方法調(diào)用者,方法名,方法參數(shù).

  • anInvocation.target 方法調(diào)用者
  • anInvocation.selector 方法名
  • [anInvocation getArgument:NULL atIndex:0]
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市袁波,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌辰狡,老刑警劉巖锋叨,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異宛篇,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)薄湿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門叫倍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人豺瘤,你說我怎么就攤上這事吆倦。” “怎么了坐求?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵蚕泽,是天一觀的道長。 經(jīng)常有香客問我桥嗤,道長须妻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任泛领,我火速辦了婚禮荒吏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘渊鞋。我一直安慰自己绰更,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布锡宋。 她就那樣靜靜地躺著儡湾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪执俩。 梳的紋絲不亂的頭發(fā)上徐钠,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音奠滑,去河邊找鬼丹皱。 笑死妒穴,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的摊崭。 我是一名探鬼主播讼油,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼呢簸!你這毒婦竟也來了矮台?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤根时,失蹤者是張志新(化名)和其女友劉穎瘦赫,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛤迎,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡确虱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了替裆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片校辩。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖辆童,靈堂內(nèi)的尸體忽然破棺而出宜咒,到底是詐尸還是另有隱情,我是刑警寧澤把鉴,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布故黑,位于F島的核電站,受9級(jí)特大地震影響庭砍,放射性物質(zhì)發(fā)生泄漏场晶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一逗威、第九天 我趴在偏房一處隱蔽的房頂上張望峰搪。 院中可真熱鬧,春花似錦凯旭、人聲如沸概耻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鞠柄。三九已至,卻和暖如春嫉柴,著一層夾襖步出監(jiān)牢的瞬間厌杜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留夯尽,地道東北人瞧壮。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像匙握,于是被迫代替她去往敵國和親咆槽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355