類執(zhí)行方法的過程與運(yùn)行時(shí)

大家都知道,調(diào)用一個(gè)未聲明方法大多數(shù)情況下會(huì)崩潰,崩潰信息就是unrecognized selector sent to instance;是的,的確大多數(shù)情況下是這樣的,但是有了運(yùn)行時(shí)就不一定了,這就是我今天的主題——“安全類”

(哈哈哈,自己隨便起的名字,會(huì)不會(huì)有點(diǎn)土。。。)

常規(guī)情況下的確是會(huì)崩潰,不過要想讓它不崩潰我們就要來研究一下一個(gè)對(duì)象去執(zhí)行方法的過程

上代碼:

先建立一個(gè)類,(我平時(shí)喜歡建立一個(gè)工程“打草稿”,就從草稿里面隨便拿一個(gè)類來說吧??)

就是這樣一個(gè)DrawImageColor這個(gè)類,創(chuàng)建了一個(gè)對(duì)象,然后利用performSelector去執(zhí)行一個(gè)未聲明的方法,不能直接[image add]這樣調(diào)用,這樣編譯都不會(huì)通過,會(huì)直接報(bào)錯(cuò),所以為了通過編譯就采用這樣的方式去調(diào)用

見證奇跡:

這里的Log是我專門打印的,為了證明這個(gè)運(yùn)行成功了,并且并沒有崩潰,然后開始介紹為什么不崩潰了!

(重點(diǎn)來了)方法調(diào)用的順序:

有這幾個(gè)方法要認(rèn)識(shí)一下

(1)、+ (BOOL)resolveInstanceMethod:(SEL)sel;

說明:當(dāng)一個(gè)對(duì)象調(diào)用未實(shí)現(xiàn)的方法,會(huì)調(diào)用這個(gè)方法處理,并且會(huì)把對(duì)應(yīng)的方法列表傳過來

(2)、- (id)forwardingTargetForSelector:(SEL)aSelector

說明:當(dāng)1??方法返回NO的時(shí)候(代表當(dāng)前類無法執(zhí)行該方法),就會(huì)執(zhí)行這個(gè)方法返回一個(gè)可以執(zhí)行這個(gè)方法的對(duì)象

(3)、- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector

說明:當(dāng)2??方法返回的對(duì)象可以執(zhí)行該方法的時(shí)候,那么程序就運(yùn)行結(jié)束了,但是如果上一個(gè)方法返回的對(duì)象是nil或者self的時(shí)候就會(huì)執(zhí)行③方法

(4)、- (void)forwardInvocation:(NSInvocation *)anInvocation

說明:當(dāng)3??方法返回的是一個(gè)有效的NSMethodSignature對(duì)象(怎么叫做有效的對(duì)象可以自己去查查,哈哈)的時(shí)候會(huì)執(zhí)行⑤方法,當(dāng)③方法返回的是一個(gè)nil的時(shí)候就會(huì)執(zhí)行6??方法

(5)、- (void)forwardInvocation:(NSInvocation *)anInvocation

說明:到這里說明3??方法中返回的是有效的NSMethodSignature對(duì)象,所以會(huì)執(zhí)行NSMethodSignature對(duì)象中的forwardInvocation函數(shù)

(6)、- (void)doesNotRecognizeSelector:(SEL)aSelector

說明:到這里程序會(huì)拋出異常并結(jié)束。

啊,終于屢完了過程,寫博客果然是個(gè)辛苦活,??

實(shí)現(xiàn)“永不崩潰的類”:

由上面的方法執(zhí)行順序我們可以這樣分析:

我們應(yīng)該在1??方法中“處理方法”,

在2??方法中返回的肯定是個(gè)nil了,要不然叫什么“永不崩潰的類”,應(yīng)該改名叫“永遠(yuǎn)甩鍋的類”??

在3??方法中我們要返回一個(gè)有效的NSMethodSignature對(duì)象,但是這個(gè)創(chuàng)建的過程中很麻煩,然后有人說可以返回nil,請注意,返回了nil之后會(huì)執(zhí)行6??方法直接拋出異常崩潰了。所以我現(xiàn)在想用運(yùn)行時(shí)來解決它,我們要在方法1??就解決這個(gè)問題??

runtime:

運(yùn)行時(shí)肯定離不開它,在這里我就截個(gè)圖針對(duì)這種情況說一下它會(huì)用到哪個(gè)方法,其實(shí)就一個(gè)方法,

在這里就會(huì)多這么一句代碼,這里也可以用來做動(dòng)態(tài)添加方法的功能,不過現(xiàn)在不說這個(gè)功能,我就是想實(shí)現(xiàn)它不崩潰,所以如上圖就使用class_addMethod添加一個(gè)已經(jīng)實(shí)現(xiàn)的方法,注意這個(gè)方法要是C語言的形式去實(shí)現(xiàn)的,然后就不會(huì)崩潰了,大家可以試一下,我在想,如果寫一個(gè)NSObject的分類,把這些方法用到NSObject的分類里去,那樣會(huì)不會(huì)所有的類都不會(huì)因?yàn)榉椒ㄎ绰暶鞅罎⒘四兀??

所以我無聊做了這個(gè)類:

用法:

不過最后想了想,沒多大意義,就刪了??

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

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

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