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

  • 數(shù)據(jù)結(jié)構(gòu):objc_object樱衷,objc_class棋嘲,isa,class_data_bits_t矩桂,cache_t沸移,method_t
  • 對象,類對象侄榴,元類對象
  • 消息傳遞
  • 消息轉(zhuǎn)發(fā)

一雹锣、數(shù)據(jù)結(jié)構(gòu):objc_object,objc_class癞蚕,isa蕊爵,class_data_bits_t,cache_t桦山,method_t

  • objc_object(id)
    isa_t,關(guān)于isa操作相關(guān)攒射,弱引用相關(guān),關(guān)聯(lián)對象相關(guān)恒水,內(nèi)存管理相關(guān)
  • objc_class (class) 繼承自objc_object
    Class superClass,cache_t cache,class_data_bits_t bits
  • isa指針会放,共用體isa_t


  • isa指向
    關(guān)于對象,其指向類對象钉凌。
    關(guān)于類對象咧最,其指向元類對象。
    實例--(isa)-->class--(isa)-->MetaClass
  • cache_t
    用于快速查找方法執(zhí)行函數(shù),是可增量擴展的哈希表結(jié)構(gòu)矢沿,是局部性原理的最佳運用
 struct cache_t {
    struct bucket_t *_buckets;//一個散列表滥搭,用來方法緩存,bucket_t類型咨察,包含key以及方法實現(xiàn)IMP
    mask_t _mask;//分配用來緩存bucket的總數(shù)
    mask_t _occupied;//表明目前實際占用的緩存bucket的個數(shù)
}
struct bucket_t {
    private:
    cache_key_t _key;
    IMP _imp;
 }
  • class_data_bits_t:對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的類的屬性论熙、方法、以及遵循的協(xié)議都放在class_rw_t中摄狱,class_rw_t代表了類相關(guān)的讀寫信息今缚,是對class_ro_t的封裝参淹,而class_ro_t代表了類的只讀信息瘪松,存儲了 編譯器決定了的屬性围小、方法和遵守協(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ù)四要素:名稱,返回值酣衷,參數(shù)交惯,函數(shù)體
struct method_t {
  SEL name;           //名稱
  const char *types;//返回值和參數(shù)
  IMP imp;              //函數(shù)體
}

二、 對象穿仪,類對象席爽,元類對象

  • 類對象存儲實例方法列表等信息。

  • 元類對象存儲類方法列表等信息啊片。


    superClass是一層層集成的,到最后NSObject的superClass是nil.而NSObject的isa指向根元類,這個根元類的isa指向它自己,而它的superClass是NSObject,也就是最后形成一個環(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)前類查找-->父類逐級查找

  • 調(diào)用方法之前,先去查找緩存紫谷,看看緩存中是否有對應(yīng)選擇器的方法實現(xiàn)齐饮,如果有,就去調(diào)用函數(shù)笤昨,完成消息傳遞(緩存查找:給定值SEL,目標(biāo)是查找對應(yīng)bucket_t中的IMP祖驱,哈希查找)
  • 如果緩存中沒有,會根據(jù)當(dāng)前實例的isa指針查找當(dāng)前類對象的方法列表瞒窒,看看是否有同樣名稱的方法 捺僻,如果找到,就去調(diào)用函數(shù)崇裁,完成消息傳遞(當(dāng)前類中查找:對于已排序好的方法列表匕坯,采用二分查找,對于沒有排序好的列表寇壳,采用一般遍歷)
  • 如果當(dāng)前類對象的方法列表沒有,就會逐級父類方法列表中查找妻怎,如果找到壳炎,就去調(diào)用函數(shù),完成消息傳遞(父類逐級查找:先判斷父類是否為nil,為nil則結(jié)束匿辩,否則就繼續(xù)進(jìn)行緩存查找-->當(dāng)前類查找-->父類逐級查找的流程)
  • 如果一直查到根類依然沒有查找到腰耙,則進(jìn)入到消息轉(zhuǎn)發(fā)流程中,完成消息傳遞

四铲球、消息轉(zhuǎn)發(fā)

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

那么最后消息未能處理的時候挺庞,還會調(diào)用到
-(void)doesNotRecognizeSelector:(SEL)aSelector`這個方法,我們也可以在這個方法中做處理稼病,避免掉crash选侨,但是只建議在線上環(huán)境的時候做處理,實際開發(fā)過程中還要把異常拋出來

  • 方法交換(Method-Swizzling)
     + (void)load
   {
       Method test = class_getInstanceMethod(self, @selector(test));
       Method otherTest = class_getInstanceMethod(self, @selector(otherTest));
       method_exchangeImplementations(test, otherTest);
   }

應(yīng)用場景:替換系統(tǒng)的方法然走,比如viewDidLoad援制,viewWillAppear以及一些響應(yīng)方法,來進(jìn)行統(tǒng)計信息

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

  • [obj foo]和objc_msgSend()函數(shù)之間有什么關(guān)系芍瑞?
    objc_msgSend()是[obj foo]的具體實現(xiàn)晨仑。在runtime中,objc_msgSend()是一個c函數(shù)拆檬,[obj foo]會被翻譯成這樣的形式objc_msgSend(obj, foo)洪己。

  • runtime是如何通過selector找到對應(yīng)的IMP地址的?
    緩存查找-->當(dāng)前類查找-->父類逐級查找

  • 能否向編譯后的類中增加實例變量竟贯?
    不能答捕。 編譯后,該類已經(jīng)完成了實例變量的布局澄耍,不能再增加實例變量噪珊。但可以向動態(tài)添加的類中增加實例變量。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末齐莲,一起剝皮案震驚了整個濱河市痢站,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌选酗,老刑警劉巖阵难,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異芒填,居然都是意外死亡呜叫,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門殿衰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來朱庆,“玉大人,你說我怎么就攤上這事闷祥∮榧眨” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長箱硕。 經(jīng)常有香客問我拴竹,道長,這世上最難降的妖魔是什么剧罩? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任栓拜,我火速辦了婚禮,結(jié)果婚禮上惠昔,老公的妹妹穿的比我還像新娘幕与。我一直安慰自己,他們只是感情好舰罚,可當(dāng)我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布纽门。 她就那樣靜靜地躺著,像睡著了一般营罢。 火紅的嫁衣襯著肌膚如雪赏陵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天饲漾,我揣著相機與錄音蝙搔,去河邊找鬼。 笑死考传,一個胖子當(dāng)著我的面吹牛吃型,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播僚楞,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼勤晚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了泉褐?” 一聲冷哼從身側(cè)響起赐写,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎膜赃,沒想到半個月后挺邀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡跳座,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年端铛,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疲眷。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡禾蚕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出狂丝,到底是詐尸還是另有隱情换淆,我是刑警寧澤虚倒,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站产舞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏菠剩。R本人自食惡果不足惜易猫,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望具壮。 院中可真熱鬧准颓,春花似錦、人聲如沸棺妓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽怜跑。三九已至样勃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間性芬,已是汗流浹背峡眶。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留植锉,地道東北人辫樱。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像俊庇,于是被迫代替她去往敵國和親狮暑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,700評論 2 354

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