Runtime相關(guān)知識點(diǎn)

各位iOS搬磚工毡熏,相信大家在面試的時候經(jīng)常會遇到Runtime相關(guān)的知識點(diǎn)坦敌,但是由于日常開發(fā)中的確很少用到,所以大家的回答也不盡人意痢法,今天就由我?guī)Т蠹姨剿饕环琑untime;

Runtime是什么:

我們都知道,將源代碼轉(zhuǎn)換為可執(zhí)行的程序杜顺,通常要經(jīng)過三個步驟:編譯财搁、鏈接、運(yùn)行躬络。不同的編譯語言尖奔,在這三個步驟中所進(jìn)行的操作又有些不同;
C語言作為一門靜態(tài)類語言,在它編譯的階段就已經(jīng)確定了所有變量的數(shù)據(jù)類型提茁,同時也確定好了要調(diào)用的函數(shù)淹禾,以及函數(shù)的實(shí)現(xiàn);
而Objective-C語言是一門動態(tài)語言茴扁。在編譯階段并不知道變量的具體數(shù)據(jù)類型铃岔,也不知道所真正調(diào)用的哪個函數(shù)。只有在運(yùn)行時間才檢查變量的數(shù)據(jù)類型峭火,同時在運(yùn)行時才會根據(jù)函數(shù)名查找要調(diào)用的具體函數(shù)毁习。這樣在程序沒運(yùn)行的時候,我們并不知道調(diào)用一個方法具體會發(fā)生什么卖丸。
Objective-C語言把一些決定性的工作從編譯階段纺且、鏈接階段推遲到了運(yùn)行時階段的機(jī)制,使得Objective-C變得更加靈活稍浆。我們甚至可以在程序運(yùn)行的時候载碌,動態(tài)的去修改一個方法的實(shí)現(xiàn)。而實(shí)現(xiàn)Objective-C語言運(yùn)行時機(jī)制的一切基礎(chǔ)就是Runtime衅枫。
Runtime其實(shí)有兩個版本:modern和legacy嫁艇。我們現(xiàn)在用的Object2.0采用的是現(xiàn)行(modern)版的Runtime系統(tǒng),只能運(yùn)行在iOS和macOS10.5之后的64位程序中为鳄。而macOS較老的32位程序扔采用Object 1中的(早期)legacy版本的Runtime系統(tǒng)裳仆。這兩個版本最大的區(qū)別在于當(dāng)你更改一個類的實(shí)例變量的布局時,在早期版本中你需要重新編譯他的子類孤钦,而現(xiàn)行版本就不需要歧斟。
Runtime基本是用C和匯編寫的,可見蘋果為了動態(tài)系統(tǒng)的高效而作出的努力偏形。蘋果和GNU(一個自由的操作系統(tǒng))各自維護(hù)一個開源的runtime版本静袖,這兩個版本之間都在努力的保持一致。
高級編程語言想要成為可執(zhí)行文件需要先編譯為匯編語言再匯編為機(jī)器語言俊扭,機(jī)器語言也是計(jì)算機(jī)能夠識別的唯一語言队橙,但是OC并不能直接編譯為匯編語言,而是要先轉(zhuǎn)寫為純C語言再進(jìn)行編譯和匯編的操作萨惑,從OC到C的過渡就是由runtime來實(shí)現(xiàn)的捐康。然后我們使用OC進(jìn)行面向?qū)ο箝_發(fā),而C語言更多的是面向過程開發(fā)庸蔼,這就需要將面向?qū)ο蟮念愞D(zhuǎn)變?yōu)槊嫦蜻^程的結(jié)構(gòu)體解总。
Runtime實(shí)際上是一個庫,這個庫使我們可以在程序運(yùn)行時動態(tài)的創(chuàng)建對象姐仅、檢查對象花枫、修改類和對象的方法刻盐。
了解Runtime,要先了解他們核心-消息傳遞(Messaging)

Runtime消息傳遞(Messaging):

Objective-C語言中劳翰,對象方法調(diào)用都是類似[receiver selector]敦锌;的形式,其本質(zhì)就是讓對象在運(yùn)行時發(fā)送消息的過程佳簸。
[receiver selector]
在編譯階段和運(yùn)行階段分別作了什么:
1.編譯階段:[ receiver selector] 方法被編譯器轉(zhuǎn)換為:
-objc_msgSend(receiver,selector)(不帶參數(shù))
-objc_msgSend(receiver,selector,org1,org2,…)(帶參數(shù))
2.運(yùn)行時階段:消息接受者receiver尋找對應(yīng)的selector乙墙。
-通過receiver的isa指針找到receiver的 Class(類);
-在Class(類)的cache(方法緩存)的散列表中尋找對應(yīng)的IMP(方法實(shí)現(xiàn))溺蕉;
-如果在cache中沒有找到對應(yīng)的IMP的話伶丐,就繼續(xù)在Class中的method list(方法列表)中找對應(yīng)的selector,如果找到疯特,填充到cache中哗魂,并且返回selector
-如果在Class類中沒有找到這個selector,就繼續(xù)在它的superClass中尋找;
-一旦找到對應(yīng)的selector漓雅,直接執(zhí)行receiver對應(yīng)selector方法實(shí)現(xiàn)的IMP录别。
-若找不到對應(yīng)的selector,消息被轉(zhuǎn)發(fā)或者臨時向receiver添加這個selector對應(yīng)的實(shí)現(xiàn)方法邻吞,否則就會發(fā)生崩潰组题。

相關(guān)應(yīng)用:黑魔法:方法添加和替換

添加方法:

//class_addMethod(Class  _Nullable __unsafe_unretained cls, SEL  _Nonnull name, IMP  _Nonnull imp, const char * _Nullable types)
class_addMethod([self class],sel,(IMP)fooMethod,”v@:”);

替換方法:

@implementation ViewController

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];
        SEL originalSelector = @selector(viewDidLoad);
        SEL swizzledSelector = @selector(jkviewDidLoad);
        
        Method originalMethod = class_getInstanceMethod(class,originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class,swizzledSelector);
        
        //judge the method named  swizzledMethod is already existed.
        BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
        // if swizzledMethod is already existed.
        if (didAddMethod) {
            class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
        }
        else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

- (void)jkviewDidLoad {
    NSLog(@"替換的方法");
    
    [self jkviewDidLoad];
}

- (void)viewDidLoad {
    NSLog(@"自帶的方法");
    
    [super viewDidLoad];
}

@end

swizzling應(yīng)該只在+load中完成。在Objective-C的運(yùn)行時中抱冷,每個類有兩個方法都會自動調(diào)用崔列。+load是在一個類被初始裝載時調(diào)用,+initialize 是在應(yīng)用第一次調(diào)用該類的類方法或?qū)嵗椒ㄇ罢{(diào)用的旺遮。兩個方法都是可選的赵讯,并且只有在方法被實(shí)現(xiàn)的情況下才會被調(diào)用。
Swizzling應(yīng)該只在dispatch_once中完成耿眉,由于swizzling改變了全局的狀態(tài)边翼,所以我們需要確保沒個預(yù)防措施在運(yùn)行時都是可用的。原子操作就是這樣一個用于確保代碼只會被執(zhí)行一次的預(yù)防措施鸣剪,就算是在不同的線程中也能確保代碼只執(zhí)行一次组底。Grand Central Dispatch的dispatch_once滿足了所需要的需求,并且應(yīng)該被當(dāng)做使用swizzling的初始化單例方法的標(biāo)準(zhǔn)筐骇;
文章收錄自行走少年郎
iOS 開發(fā):『Runtime』詳解(一)基礎(chǔ)知識
以及jackyshan
iOS Runtime詳解

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末债鸡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子铛纬,更是在濱河造成了極大的恐慌娘锁,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件饺鹃,死亡現(xiàn)場離奇詭異莫秆,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)悔详,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門镊屎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人茄螃,你說我怎么就攤上這事缝驳。” “怎么了归苍?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵用狱,是天一觀的道長。 經(jīng)常有香客問我拼弃,道長夏伊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任吻氧,我火速辦了婚禮溺忧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘盯孙。我一直安慰自己鲁森,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布振惰。 她就那樣靜靜地躺著歌溉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪骑晶。 梳的紋絲不亂的頭發(fā)上痛垛,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機(jī)與錄音透罢,去河邊找鬼榜晦。 笑死,一個胖子當(dāng)著我的面吹牛羽圃,可吹牛的內(nèi)容都是我干的乾胶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼朽寞,長吁一口氣:“原來是場噩夢啊……” “哼识窿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起脑融,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤喻频,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后肘迎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體甥温,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锻煌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了姻蚓。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宋梧。...
    茶點(diǎn)故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖狰挡,靈堂內(nèi)的尸體忽然破棺而出捂龄,到底是詐尸還是另有隱情,我是刑警寧澤加叁,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布倦沧,位于F島的核電站,受9級特大地震影響它匕,放射性物質(zhì)發(fā)生泄漏展融。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一超凳、第九天 我趴在偏房一處隱蔽的房頂上張望愈污。 院中可真熱鬧,春花似錦轮傍、人聲如沸暂雹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽杭跪。三九已至,卻和暖如春驰吓,著一層夾襖步出監(jiān)牢的瞬間涧尿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工檬贰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留姑廉,地道東北人。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓翁涤,卻偏偏與公主長得像桥言,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子葵礼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 本文詳細(xì)整理了 Cocoa 的 Runtime 系統(tǒng)的知識号阿,它使得 Objective-C 如虎添翼,具備了靈活的...
    lylaut閱讀 800評論 0 4
  • 本文轉(zhuǎn)載自:http://yulingtianxia.com/blog/2014/11/05/objective-...
    ant_flex閱讀 758評論 0 1
  • 繼上Runtime梳理(四) 通過前面的學(xué)習(xí)鸳粉,我們了解到Objective-C的動態(tài)特性:Objective-C不...
    小名一峰閱讀 752評論 0 3
  • 我們常常會聽說 Objective-C 是一門動態(tài)語言扔涧,那么這個「動態(tài)」表現(xiàn)在哪呢?我想最主要的表現(xiàn)就是 Obje...
    Ethan_Struggle閱讀 2,192評論 0 7
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,097評論 1 32