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




- OC的類信息存放在哪里?
- 對象方法、屬性、成員變量、協(xié)議信息,存放在class對象中
- 類方法,存放在meta-class對象中
- 成員變量的具體值,存放在instance對象
- 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


5.1 通過KVC修改屬性會觸發(fā)KVO么?
- 會觸發(fā)KVO
5.2 KVC的賦值和取值過程是怎樣的?原理是什么?


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)用順序
- 先調(diào)用類的+load
按照編譯先后順序調(diào)用(先編譯,先調(diào)用)
調(diào)用子類的+load之前會先調(diào)用父類的+load - 再調(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方法

-
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)?



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





