iOS面試題(夯實(shí)基礎(chǔ)學(xué)習(xí)筆記-溫故知新)

  1. 一個NSObject對象占用多少內(nèi)存?

    • 系統(tǒng)分配了16個字節(jié)給NSObject對象(通過malloc_size函數(shù)獲得)
      但NSObject對象內(nèi)部只使用了8個字節(jié)的空間(64bit環(huán)境下,可以通過class_getInstanceSize函數(shù)獲得)
  2. 對象的isa指針指向哪里?

    • instance對象的isa指向class對象
    • class對象的isa指向meta-class對象
    • meta-class對象的isa指向基類的meta-class對象
isa指針.png

class對象的superclass指針 .png

meta-class對象的superclass指針 .png

image.png
  1. OC的類信息存放在哪里?
    • 對象方法、屬性、成員變量、協(xié)議信息,存放在class對象中
    • 類方法,存放在meta-class對象中
    • 成員變量的具體值,存放在instance對象
  2. iOS用什么方式實(shí)現(xiàn)對一個對象的KVO?(KVO的本質(zhì)是什么?)
    • 利用RuntimeAPI動態(tài)生成一個子類,并且讓instance對象的isa指向這個全新的子類
    • 當(dāng)修改instance對象的屬性時(shí),會調(diào)用Foundation的_NSSetXXXValueAndNotify函數(shù)
      • willChangeValueForKey:
      • 父類原來的setter
      • didChangeValueForKey:
    • 內(nèi)部會觸發(fā)監(jiān)聽器(Oberser)的監(jiān)聽方法( observeValueForKeyPath:ofObject:change:context:)

4.1. 如何手動觸發(fā)KVO?

  • 手動調(diào)用willChangeValueForKey:和didChangeValueForKey:

4.2. 直接修改成員變量會觸發(fā)KVO么?

  • 不會觸發(fā)KVO
未使用KVO監(jiān)聽的對象.png

使用了KVO監(jiān)聽的對象 .png

5.1 通過KVC修改屬性會觸發(fā)KVO么?

  • 會觸發(fā)KVO

5.2 KVC的賦值和取值過程是怎樣的?原理是什么?


setValue:forKey:的原理.png

valueForKey:的原理.png

6.1 Category的使用場合是什么?

6.2 Category的實(shí)現(xiàn)原理

  • Category編譯之后的底層結(jié)構(gòu)是struct category_t,里面存儲著分類的對象方法、類方法、屬性、協(xié)議信息
  • 在程序運(yùn)行的時(shí)候,runtime會將Category的數(shù)據(jù),合并到類信息中(類對象、元類對象中)
    n


    category的底層結(jié)構(gòu).png

6.3 Category和Class Extension的區(qū)別是什么?

  • Class Extension在編譯的時(shí)候,它的數(shù)據(jù)就已經(jīng)包含在類信息中
  • Category是在運(yùn)行時(shí),才會將數(shù)據(jù)合并到類信息中

6.4 Category中有l(wèi)oad方法嗎?load方法是什么時(shí)候調(diào)用的?load 方法能繼承嗎?

load

  • 有l(wèi)oad方法
  • load方法在runtime加載類、分類的時(shí)候調(diào)用
  • load方法可以繼承,但是一般情況下不會主動去調(diào)用load方法,都是讓系統(tǒng)自動調(diào)用

6.5 load、initialize方法的區(qū)別什么?它們在category中的調(diào)用的順序?以及出現(xiàn)繼承時(shí)他們之間的調(diào)用過程?

  • +load方法會在runtime加載類、分類時(shí)調(diào)用
  • 每個類、分類的+load,在程序運(yùn)行過程中只調(diào)用一次

在category調(diào)用順序

  1. 先調(diào)用類的+load
    按照編譯先后順序調(diào)用(先編譯,先調(diào)用)
    調(diào)用子類的+load之前會先調(diào)用父類的+load
  2. 再調(diào)用分類的+load
    按照編譯先后順序調(diào)用(先編譯,先調(diào)用)

+load方法是根據(jù)方法地址直接調(diào)用,并不是經(jīng)過objc_msgSend函數(shù)調(diào)用

initialize

  • +initialize方法會在類第一次接收到消息時(shí)調(diào)用
    調(diào)用順序
    • 先調(diào)用父類的+initialize,再調(diào)用子類的+initialize
    • (先初始化父類,再初始化子類,每個類只會初始化1次)

區(qū)別

+initialize和+load的很大區(qū)別是

  • +initialize是通過objc_msgSend進(jìn)行調(diào)用的,所以有以下特點(diǎn)
  • 如果子類沒有實(shí)現(xiàn)+initialize,會調(diào)用父類的+initialize(所以父類的+initialize可能會被調(diào)用多次)
  • 如果分類實(shí)現(xiàn)了+initialize,就覆蓋類本身的+initialize調(diào)用

6.6 Category能否添加成員變量?如果可以,如何給Category添加成員變量?

  • 不能直接給Category添加成員變量,但是可以間接實(shí)現(xiàn)Category有成員變量的效果

解釋:

  • 屬性添加類中對應(yīng)的操作有3步
    1.添加成員變量
    2.聲明set、get方法
    3.實(shí)現(xiàn)set、get 方法
  • 屬性添加到分類中對應(yīng)的操作只有1步
    1.聲明set、get方法

關(guān)聯(lián)對象.png
  1. 1 block的原理是怎樣的?本質(zhì)是什么?
    封裝了函數(shù)調(diào)用以及調(diào)用環(huán)境的OC對象


    block的本質(zhì).png

    block的變量捕獲.png

    auto變量的捕獲.png

    block的類型1.png

    block的類型2.png

7.2__block的作用是什么?有什么使用注意點(diǎn)?


image.png

image.png

image.png

7.3 block的屬性修飾詞為什么是copy?使用block有哪些使用注意?
block一旦沒有進(jìn)行copy操作,就不會在堆上
使用注意:循環(huán)引用問題

7.4 block在修改NSMutableArray,需不需要添加__block?

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

友情鏈接更多精彩內(nèi)容