iOS開發之原來Runtime的黑魔法這麼厲害

2021-09-24 06:43:45 字數 2226 閱讀 7816

學習ios以來不間斷的會聽到runtime,開始感覺oc的語法已經很完善了根本沒有必要學習它背後的執行機制,一直以來對這塊知識點置若罔聞的我,今天竟然認認真真的讀了一篇runtime的文章,然後就被它深深地吸引住了^_^

今天在這裡小菜鳥不會羅列runtime的語法,但會通過乙個簡單的runtime例項的認真講解讓大傢伙領會runtime的魅力所在。

**1、例項內容:**通過runtime來阻止陣列越界

nsarray *array=[[nsarray alloc]initwithobjects:@"111",@"222", nil]; 

[array objectatindex:3];

複製**

遇到上述用法直接導致的後果就是我們的程式會崩掉,在開發中遇到我們還可以修改程式,但使用者實際使用時崩掉就會閃退,這會使使用者體驗大大折扣的。

那有沒有一種可能在越界的時候,如果我們處於除錯過程就讓它跳出錯誤,而當使用者使用時越界就不讓它崩潰呢。答案是肯定的,那接下來小菜鳥就帶領大家一起領略runtime的黑魔法。

3、runtime的黑魔法講解首先我們要明確下需求:

下面是我寫的乙個nsarray的類別,**:

@implementation nsarray (boundary)

+(void)load);

}複製**

-(id)safeobjectatindex:(nsuinteger)index

else

}@end

複製**

這些**什麼意思呢,小菜鳥接下來會分段講解的。

+(void)load

複製**

這個方法是在建立分類的時候系統會自動呼叫的方法

static dispatch_once_t oncetoken;

dispatch_once(&oncetoken, ^);

複製**

這句**我們單利中常常會用到,保證**只執行一次就不多做解釋了。

sel safesel=@selector(safeobjectatindex:);

sel unsafesel=@selector(objectatindex:);

複製**

objc_selector結構體的詳細定義沒有在標頭檔案中找到。方法的selector用於表示執行時方 法的名字。objective-c在編譯時,會依據每乙個方法的名字、引數序列,生成乙個唯一的整型標識(int型別的位址),這個標識就是sel。

method safemethod=class_getinstancemethod (myclass, safesel);

method unsafemethod=class_getinstancemethod (myclass, unsafesel);

複製**

使用runtime方法拿到例項中的方法

method_exchangeimplementations(unsafemethod, safemethod);

複製**

交換sel對應的imp實現。

總的來說我們就是將objectatindex:和safeobjectatindex:兩個函式互換了,也就是說我們在應用中如果呼叫objectatindex:實際上我們呼叫的是safeobjectatindex:這個方法。

這裡還要補充一點的就是在safeobjectatindex:中我們寫了這麼一句return [self safeobjectatindex:index];是什麼意思呢,難道不會迴圈呼叫?當然不會!

當我們外部呼叫objectatindex:時才會呼叫safeobjectatindex:,而return中呼叫safeobjectatindex:實際上呼叫的就是objectatindex:。哈哈感覺有點饒了,其實就是兩個函式已經通過runtime互換了。

nsassert(no, @"beyond the boundary");

複製**

在方法-(id)safeobjectatindex:(nsuinteger)index中用到的這個就是oc中的斷言,簡單講就是當程式處於debug模式時會給我們跑出錯誤資訊,而處於release模式時也就是使用者使用程式時不會丟擲資訊而導致閃退。

後續還會更新更多runtime的例項,喜歡就點喜歡吧^_^

iOS開發 runtime機制

runtime簡稱執行時。就是系統在執行的時候的一些機制,其中最主要的是訊息機制。對於c語言,函式的呼叫在編譯的時候會決定呼叫哪個函式 c語言的函式呼叫請看這裡 編譯完成之後直接順序執行,無任何二義性。oc的函式呼叫成為訊息傳送。屬於動態呼叫過程。在編譯的時候並不能決定真正呼叫哪個函式 事實證明,在...

IOS高階開發 Runtime(三)

11 系統類的方法實現部分替換 void methodexchange 列印結果 仔細看log 2013 07 26 16 33 22.776 highoc 7104 c07 sssaaaass 2013 07 26 16 33 22.778 highoc 7104 c07 sssaaaass 12...

IOS高階開發 Runtime(三)

11 系統類的方法實現部分替換 void methodexchange 列印結果 仔細看log 2013 07 26 16 33 22.776 highoc 7104 c07 sssaaaass 2013 07 26 16 33 22.778 highoc 7104 c07 sssaaaass 12...