OC面試題總結

一、面向對象

1.1 一個NSObject對象佔用多少內存?

  • 系統分配了16個字節給NSObject對象(通過malloc_size函數獲得)
  • 但NSObject對象內部只使用了8個字節的空間(64bit環境下,可以通過class_getInstanceSize函數獲得)

1.2 對象的isa指針指向哪裏?

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

1.3 OC的類信息存放在哪裏?

  • 對象方法、屬性、成員變量、協議信息,存放在class對象中 - 類方法,存放在meta-class對象中
  • 成員變量的具體值,存放在instance對象

二、KVO

2.1 iOS用什麼方式實現對一個對象的KVO?(KVO的本質是什麼?)

  • 利用RuntimeAPI動態生成一個子類,並且讓instance對象的isa指向這個全新的子類
  • 當修改instance對象的屬性時,會調用Foundation的_NSSetXXXValueAndNotify函數
    • willChangeValueForKey:
    • 父類原來的setter
    • didChangeValueForKey:
      • 內部會觸發監聽器(Oberser)的監聽方法( observeValueForKeyPath:ofObject:change:context:)

2.2 如何手動觸發KVO?

  • 手動調用willChangeValueForKey:和didChangeValueForKey:

2.3 直接修改成員變量會觸發KVO麼?

  • 不會觸發KVO

三、KVC

3.1 通過KVC修改屬性會觸發KVO麼?

  • 會觸發KVO

3.2 KVC的賦值和取值過程是怎樣的?原理是什麼?

四、Category

4.1 Category的使用場合是什麼?

4.2 Category的實現原理

  • Category編譯之後的底層結構是struct category_t,裏面存儲着分類的對象方法、類方法、屬性、協議信息
  • 在程序運行的時候,runtime會將Category的數據,合併到類信息中(類對象、元類對象中)

4.3 包含分類的類中的方法列表順序

  • 方法列表順序
  1. 編譯文件靠後的分類的方法先導入方法列表
  2. 最後把當前類的方法導入方法列表
  • 比如
  1. MJPerson+Eat.h中有run, eat兩個對象方法
  2. MJPerson+Test.h中有run, test兩個對象方法
  3. MJPerson.h中有run一個對象方法
  4. 編譯順序如下
    • MJPerson+Eat.m
    • MJPerson.m
    • MJPerson+Test.m
  5. 那麼MJPerson類對象的方法列表爲
    • MJPerson+Test的run, test方法
    • MJPerson+Eat的run, eat方法
    • MJPerson的run方法
  • 查看文件的編譯順序
    在這裏插入圖片描述
  • 修改文件編譯順序
    在這裏插入圖片描述

4.3 Category和Class Extension的區別是什麼?

  • Class Extension在編譯的時候,它的數據就已經包含在類信息中
  • Category是在運行時,纔會將數據合併到類信息中

4.4 Category中有load方法嗎?load方法是什麼時候調用的?load 方法能繼承嗎?

  • 有load方法
  • load方法在runtime加載類、分類的時候調用
  • load方法可以繼承,但是一般情況下不會主動去調用load方法,都是讓系統自動調用

4.5 load、initialize方法的區別什麼?它們在category中的調用的順序?以及出現繼承時他們之間的調用過程?

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

  • 不能直接給Category添加成員變量,但是可以間接實現Category有成員變量的效果
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章