RunTime-動態(tài)運行時

RunTime簡介:

RunTime簡稱運行時。OC就是運行時機制,也就是運行時候的一些機制,其中最主要的就是消息機制。
對于C語言,函數(shù)的調用在編譯的時候就會決定調用哪個函數(shù),如果調用未實現(xiàn)的函數(shù)就會報錯。對于OC語言,他是一門動態(tài)的語言,因為他在編譯的時候并不能決定真正調用的是哪個函數(shù),只有在真正運行的時候才會根據(jù)函數(shù)的名稱找到對應的函數(shù)進行調用。在編譯階段,OC可以調用任何函數(shù),即使這個函數(shù)并未實現(xiàn),只要聲明過就不會報錯。

RunTime消息機制

消息機制是運行時里面最重要的機制,OC中任何方法的調用,本質都是發(fā)送消息。

@selector(SEL):

這是一個方法選擇器。主要作用是快速的通過方法名字查找到對應方法的函數(shù)指針,然后調用其函數(shù)也就是IMP。SEL其本身是一個Int類型的地址,地址中存放著方法名字。對于一個類中,每一個方法對應著一個SEL。所以一個類中不能存在兩個名稱相同的方法,即使參數(shù)類型不同也不行,因為SEL是根據(jù)方法名字生成的,相同的方法名稱只能對應一個SEl。

實例方法和類方法的調用過程

屏幕快照 2019-10-14 上午10.07.40.png

實例方法的調用過程:首先會根據(jù)實例對象的isa指針找到他的類對象,在類對象的對象方法列表中去查找是否有對應實現(xiàn),如果有就調用,沒有就依次去類對象的父類中查找,一直找到NSObject還沒有的話會進入消息轉發(fā),如果在消息轉發(fā)流程(其中有三個方法)還是沒有做處理,就會報找不到方法異常。

[圖片上傳中...(屏幕快照 2019-10-14 上午10.04.48.png-68eabe-1571018691218-0)]

類方法的調用過程:首先也是會根據(jù)類對象的isa指針找到它的元類,元類中存儲著類方法列表,如果當前元類的類方法列表沒有,再依次去元類的父類中查找對應實現(xiàn),一直找到根元類,還是沒有的話,這個時候與實例方法調用不同的是,如果類對象里面有同名的實例方法,就回去調用同名的實例方法。如果沒有在進入消息轉發(fā),消息轉發(fā)沒做處理的話就會報找不到方法異常。

屏幕快照 2019-10-14 上午10.05.27.png

Runtime的應用:

獲取列表

    Method *methods = class_copyMethodList([UITextView class], &count);
    for (int i = 0; i < count; i++) {
        Method method = methods[i];
        SEL selector = method_getName(method);
        NSString *name = NSStringFromSelector(selector);
        NSLog(@"method_getName:%@",name);
    }
    
    unsigned int numIvars;
    Ivar *vars = class_copyIvarList([UITextView class], &numIvars);
    NSString *key=nil;
    for(int i = 0; i < numIvars; i++) {
        
        Ivar thisIvar = vars[i];
        key = [NSString stringWithUTF8String:ivar_getName(thisIvar)];
        NSLog(@"variable_name :%@", key);
    }

1.獲取列表(比如獲取類的屬性列表,方法列表,成員變量列表)。比如實際開發(fā)中做歸檔解檔的時候對象的屬性很多的時候就可以用RunTime這個特性很方便的簡化代碼。
2.方法調用:正如上面所講的實例方法調用和類方法調用。
3.攔截調用:攔截調用就是,在找不到調用的方法程序奔潰之前,你有機會通過重寫NSObject的四個方法來處理。
4.動態(tài)添加方法:如果一個類方法非常多,其中可能許多方法暫時用不到。而加載類方法到內存的時候需要給每個方法生成映射表,比較耗費資源,這個時候就可以用Runtime動態(tài)添加方法。動態(tài)給某個類添加方法,相當于懶加載機制,類中許多方法暫時用不到,那么就先不加載,等用的時候再去加載。另外如果找不到對應的方法時就會來到攔截調用,也就是因為找不到方法實現(xiàn),在奔潰之前可以調用的方法。當調用了沒有實現(xiàn)的對象方法時,就會調用+(BOOL)resolveInstanceMethod:(SEL)sel方法當調用了沒有實現(xiàn)的類方法時,就會調用+(BOOL)resolveClassMethod:(SEL)sel方法,我們就可以實現(xiàn)這兩個方法動態(tài)的給實例方法或者類方法添加方法和方法實現(xiàn)。
5.方法交換:當系統(tǒng)自帶的方法功能不夠,需要給系統(tǒng)自帶的方法擴展一些功能,并且保持原有的功能時,可以使用Runtime交換方法實現(xiàn)。這個特性可以用來處理開發(fā)中常見的奔潰(比如字典添加nil值,和數(shù)組越界等導致的奔潰)或者是統(tǒng)一添加埋點,可以很方便的解決這些問題。

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

相關閱讀更多精彩內容

友情鏈接更多精彩內容