2019 iOS面試題---runtime相關(guān)

2019 iOS面試題大全---全方面剖析面試
  • 數(shù)據(jù)結(jié)構(gòu):objc_object,objc_class,isa殴穴,class_data_bits_t柴钻,cache_t淮韭,method_t
  • 對(duì)象,類(lèi)對(duì)象贴届,元類(lèi)對(duì)象
  • 消息傳遞
  • 消息轉(zhuǎn)發(fā)

一靠粪、數(shù)據(jù)結(jié)構(gòu):objc_object,objc_class毫蚓,isa占键,class_data_bits_t,cache_t元潘,method_t

image.png

  • objc_object(id)
    isa_t,關(guān)于isa操作相關(guān)畔乙,弱引用相關(guān),關(guān)聯(lián)對(duì)象相關(guān)翩概,內(nèi)存管理相關(guān)
  • objc_class (class) 繼承自objc_object
    Class superClass,cache_t cache,class_data_bits_t bits
  • isa指針牲距,共用體isa_t


    image.png
  • isa指向
    關(guān)于對(duì)象,其指向類(lèi)對(duì)象钥庇。
    關(guān)于類(lèi)對(duì)象牍鞠,其指向元類(lèi)對(duì)象。
    實(shí)例--(isa)-->class--(isa)-->MetaClass
  • cache_t
    用于快速查找方法執(zhí)行函數(shù)评姨,是可增量擴(kuò)展的哈希表結(jié)構(gòu)难述,是局部性原理的最佳運(yùn)用
 struct cache_t {
    struct bucket_t *_buckets;//一個(gè)散列表,用來(lái)方法緩存,bucket_t類(lèi)型胁后,包含key以及方法實(shí)現(xiàn)IMP
    mask_t _mask;//分配用來(lái)緩存bucket的總數(shù)
    mask_t _occupied;//表明目前實(shí)際占用的緩存bucket的個(gè)數(shù)
}
struct bucket_t {
    private:
    cache_key_t _key;
    IMP _imp;
 }
  • class_data_bits_t:對(duì)class_rw_t的封裝
struct class_rw_t {
     uint32_t flags;
     uint32_t version;

     const class_ro_t *ro;

     method_array_t methods;
     property_array_t properties;
     protocol_array_t protocols;

     Class firstSubclass;
     Class nextSiblingClass;

     char *demangledName;
}    

Objc的類(lèi)的屬性店读、方法、以及遵循的協(xié)議都放在class_rw_t中攀芯,class_rw_t代表了類(lèi)相關(guān)的讀寫(xiě)信息屯断,是對(duì)class_ro_t的封裝,而class_ro_t代表了類(lèi)的只讀信息敲才,存儲(chǔ)了 編譯器決定了的屬性裹纳、方法和遵守協(xié)議

struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;
    #ifdef __LP64__
    uint32_t reserved;
    #endif

    const uint8_t * ivarLayout;
    
    const char * name;
    method_list_t * baseMethodList;
    protocol_list_t * baseProtocols;
    const ivar_list_t * ivars;

    const uint8_t * weakIvarLayout;
    property_list_t *baseProperties;

    method_list_t *baseMethods() const {
        return baseMethodList;
    }
  };
  • method_t
    函數(shù)四要素:名稱(chēng),返回值紧武,參數(shù)剃氧,函數(shù)體
struct method_t {
  SEL name;           //名稱(chēng)
  const char *types;//返回值和參數(shù)
  IMP imp;              //函數(shù)體
}

二、 對(duì)象阻星,類(lèi)對(duì)象朋鞍,元類(lèi)對(duì)象

  • 類(lèi)對(duì)象存儲(chǔ)實(shí)例方法列表等信息。

  • 元類(lèi)對(duì)象存儲(chǔ)類(lèi)方法列表等信息妥箕。

    image.png

    superClass是一層層集成的,到最后NSObject的superClass是nil.而NSObject的isa指向根元類(lèi),這個(gè)根元類(lèi)的isa指向它自己,而它的superClass是NSObject,也就是最后形成一個(gè)環(huán),
    三滥酥、消息傳遞

    void objc_msgSend(void /* id self, SEL op, ... */ )
    
    void objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... */ )
    
    struct objc_super {
        /// Specifies an instance of a class.
        __unsafe_unretained _Nonnull id receiver;
    
        /// Specifies the particular superclass of the instance to message. 
    #if !defined(__cplusplus)  &&  !__OBJC2__
        /* For compatibility with old objc-runtime.h header */
        __unsafe_unretained _Nonnull Class class;
    #else
        __unsafe_unretained _Nonnull Class super_class;
    #endif
        /* super_class is the first class to search */
    };
    

消息傳遞的流程:緩存查找-->當(dāng)前類(lèi)查找-->父類(lèi)逐級(jí)查找

  • 調(diào)用方法之前,先去查找緩存畦幢,看看緩存中是否有對(duì)應(yīng)選擇器的方法實(shí)現(xiàn)坎吻,如果有,就去調(diào)用函數(shù)宇葱,完成消息傳遞(緩存查找:給定值SEL,目標(biāo)是查找對(duì)應(yīng)bucket_t中的IMP瘦真,哈希查找)
  • 如果緩存中沒(méi)有,會(huì)根據(jù)當(dāng)前實(shí)例的isa指針查找當(dāng)前類(lèi)對(duì)象的方法列表黍瞧,看看是否有同樣名稱(chēng)的方法 诸尽,如果找到,就去調(diào)用函數(shù)印颤,完成消息傳遞(當(dāng)前類(lèi)中查找:對(duì)于已排序好的方法列表您机,采用二分查找,對(duì)于沒(méi)有排序好的列表年局,采用一般遍歷)
  • 如果當(dāng)前類(lèi)對(duì)象的方法列表沒(méi)有际看,就會(huì)逐級(jí)父類(lèi)方法列表中查找,如果找到矢否,就去調(diào)用函數(shù)仿村,完成消息傳遞(父類(lèi)逐級(jí)查找:先判斷父類(lèi)是否為nil,為nil則結(jié)束兴喂,否則就繼續(xù)進(jìn)行緩存查找-->當(dāng)前類(lèi)查找-->父類(lèi)逐級(jí)查找的流程)
  • 如果一直查到根類(lèi)依然沒(méi)有查找到,則進(jìn)入到消息轉(zhuǎn)發(fā)流程中,完成消息傳遞

四衣迷、消息轉(zhuǎn)發(fā)

+ (BOOL)resolveInstanceMethod:(SEL)sel;//為對(duì)象方法進(jìn)行決議
+ (BOOL)resolveClassMethod:(SEL)sel;//為類(lèi)方法進(jìn)行決議
- (id)forwardingTargetForSelector:(SEL)aSelector;//方法轉(zhuǎn)發(fā)目標(biāo)
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;
- (void)forwardInvocation:(NSInvocation *)anInvocation;

image.png

那么最后消息未能處理的時(shí)候畏鼓,還會(huì)調(diào)用到
- (void)doesNotRecognizeSelector:(SEL)aSelector這個(gè)方法,我們也可以在這個(gè)方法中做處理壶谒,避免掉crash云矫,但是只建議在線上環(huán)境的時(shí)候做處理,實(shí)際開(kāi)發(fā)過(guò)程中還要把異常拋出來(lái)

  • 方法交換(Method-Swizzling)

      + (void)load
    {
        Method test = class_getInstanceMethod(self, @selector(test));
    
        Method otherTest = class_getInstanceMethod(self, @selector(otherTest));
    
        method_exchangeImplementations(test, otherTest);
    }
    

應(yīng)用場(chǎng)景:替換系統(tǒng)的方法汗菜,比如viewDidLoad让禀,viewWillAppear以及一些響應(yīng)方法,來(lái)進(jìn)行統(tǒng)計(jì)信息

  • 動(dòng)態(tài)添加方法

    class_addMethod(self, sel, testImp, "v@:");
    
    void testImp (void)
    {
        NSLog(@"testImp");
    }
    
  • @dynamic 動(dòng)態(tài)方法解析
    動(dòng)態(tài)運(yùn)行時(shí)語(yǔ)言將函數(shù)決議推遲到運(yùn)行時(shí)
    編譯時(shí)語(yǔ)言在編譯期進(jìn)行函數(shù)決議

  • [obj foo]和objc_msgSend()函數(shù)之間有什么關(guān)系陨界?
    objc_msgSend()是[obj foo]的具體實(shí)現(xiàn)巡揍。在runtime中,objc_msgSend()是一個(gè)c函數(shù)菌瘪,[obj foo]會(huì)被翻譯成這樣的形式objc_msgSend(obj, foo)腮敌。

  • runtime是如何通過(guò)selector找到對(duì)應(yīng)的IMP地址的?
    緩存查找-->當(dāng)前類(lèi)查找-->父類(lèi)逐級(jí)查找

  • 能否向編譯后的類(lèi)中增加實(shí)例變量俏扩?
    不能糜工。 編譯后,該類(lèi)已經(jīng)完成了實(shí)例變量的布局录淡,不能再增加實(shí)例變量捌木。
    但可以向動(dòng)態(tài)添加的類(lèi)中增加實(shí)例變量。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末嫉戚,一起剝皮案震驚了整個(gè)濱河市刨裆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌彼水,老刑警劉巖崔拥,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異凤覆,居然都是意外死亡链瓦,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)盯桦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)慈俯,“玉大人,你說(shuō)我怎么就攤上這事拥峦√欤” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵略号,是天一觀的道長(zhǎng)刑峡。 經(jīng)常有香客問(wèn)我洋闽,道長(zhǎng),這世上最難降的妖魔是什么突梦? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任诫舅,我火速辦了婚禮,結(jié)果婚禮上宫患,老公的妹妹穿的比我還像新娘刊懈。我一直安慰自己,他們只是感情好娃闲,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布虚汛。 她就那樣靜靜地躺著,像睡著了一般皇帮。 火紅的嫁衣襯著肌膚如雪卷哩。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,146評(píng)論 1 297
  • 那天玲献,我揣著相機(jī)與錄音殉疼,去河邊找鬼。 笑死捌年,一個(gè)胖子當(dāng)著我的面吹牛瓢娜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播礼预,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼眠砾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了托酸?” 一聲冷哼從身側(cè)響起褒颈,我...
    開(kāi)封第一講書(shū)人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎励堡,沒(méi)想到半個(gè)月后谷丸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡应结,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年刨疼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鹅龄。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡揩慕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出扮休,到底是詐尸還是另有隱情迎卤,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布玷坠,位于F島的核電站蜗搔,受9級(jí)特大地震影響劲藐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜碍扔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一瘩燥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧不同,春花似錦、人聲如沸溶耘。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)凳兵。三九已至百新,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間庐扫,已是汗流浹背饭望。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留形庭,地道東北人铅辞。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像萨醒,于是被迫代替她去往敵國(guó)和親斟珊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉富纸,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,709評(píng)論 0 9
  • 我們常常會(huì)聽(tīng)說(shuō) Objective-C 是一門(mén)動(dòng)態(tài)語(yǔ)言囤踩,那么這個(gè)「動(dòng)態(tài)」表現(xiàn)在哪呢?我想最主要的表現(xiàn)就是 Obje...
    Ethan_Struggle閱讀 2,192評(píng)論 0 7
  • Objective-C語(yǔ)言是一門(mén)動(dòng)態(tài)語(yǔ)言晓褪,他將很多靜態(tài)語(yǔ)言在編譯和鏈接時(shí)期做的事情放到了運(yùn)行時(shí)來(lái)處理堵漱。這種動(dòng)態(tài)語(yǔ)言...
    tigger丨閱讀 1,398評(píng)論 0 8
  • 本文轉(zhuǎn)載自:http://yulingtianxia.com/blog/2014/11/05/objective-...
    ant_flex閱讀 758評(píng)論 0 1
  • 參考鏈接: http://www.cnblogs.com/ioshe/p/5489086.html 簡(jiǎn)介 Runt...
    樂(lè)樂(lè)的簡(jiǎn)書(shū)閱讀 2,135評(píng)論 0 9