什么時候會報unrecognized selector的異常?


簡單說就是當(dāng)調(diào)用對象的某個方法時,該對象未實現(xiàn)此方法,就會出現(xiàn)這種情況。

其實面試的時候問這個面試官就是想了解OC消息轉(zhuǎn)發(fā)機(jī)制。

objc是動態(tài)語言,每個方法在運行時會被動態(tài)轉(zhuǎn)為消息發(fā)送,即:objc_msgSend(receiver, selector)。

objc在向一個對象發(fā)送消息時,runtime庫會根據(jù)對象的isa指針找到該對象實際所屬的類,然后在該類中的方法列表以及其父類方法列表中尋找方法運行,如果,在最頂層的父類中依然找不到相應(yīng)的方法時,程序在運行時會掛掉并拋出異常unrecognized selector sent to XXX 。但是在這之前,objc的運行時會給出三次拯救程序崩潰的機(jī)會:

  • Method resolution
    objc運行時會調(diào)用+resolveInstanceMethod:或者 +resolveClassMethod:,讓你有機(jī)會提供一個函數(shù)實現(xiàn)。如果你添加了函數(shù),那運行時系統(tǒng)就會重新啟動一次消息發(fā)送的過程,否則 ,運行時就會移到下一步,消息轉(zhuǎn)發(fā)(Message Forwarding)。

  • Fast forwarding
    如果目標(biāo)對象實現(xiàn)了-forwardingTargetForSelector:,Runtime 這時就會調(diào)用這個方法,給你把這個消息轉(zhuǎn)發(fā)給其他對象的機(jī)會。
    只要這個方法返回的不是nil和self,整個消息發(fā)送的過程就會被重啟,當(dāng)然發(fā)送的對象會變成你返回的那個對象。否則,就會繼續(xù)Normal Fowarding。
    這里叫Fast,只是為了區(qū)別下一步的轉(zhuǎn)發(fā)機(jī)制。因為這一步不會創(chuàng)建任何新的對象,但下一步轉(zhuǎn)發(fā)會創(chuàng)建一個NSInvocation對象,所以相對更快點。

  • Normal forwarding
    這一步是Runtime最后一次給你挽救的機(jī)會。首先它會發(fā)送-methodSignatureForSelector:消息獲得函數(shù)的參數(shù)和返回值類型。如果-methodSignatureForSelector:返回nil,Runtime則會發(fā)出-doesNotRecognizeSelector:消息,程序這時也就掛掉了。如果返回了一個函數(shù)簽名,Runtime就會創(chuàng)建一個NSInvocation對象并發(fā)送-forwardInvocation:消息給目標(biāo)對象。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容