(1)OC中給nil對象發(fā)送消息程序是否會crash?
OC向nil發(fā)送消息,是不會崩潰的。
OC的函數(shù)調(diào)用都是通過objc_msgSend進行消息發(fā)送來實現(xiàn),相對于C/C++來說,操作空指針引起crash問題,objc_msgSend通過判斷self來決定是否發(fā)送消息,self為nil,那么selector也為空,直接返回,所以不會崩潰。向nil發(fā)消息可能會返回nil(對象)、0(基礎(chǔ)數(shù)據(jù)類型)或0x0(id類型),但對[NSNull null]對象發(fā)消息時,會造成crash,因為NSNull類只有一個null方法。若對象已被釋放,引用計數(shù)為0,去調(diào)用方法肯定也會crash,訪問了野指針。那么,安全的做法就是將釋放的對象置為nil,變?yōu)榭罩羔槨?/p>
注意:
在使用一個對象前判斷它是否為nil,好處:1.降低時間復(fù)雜度,當為nil就不需要對其發(fā)送消息,節(jié)省資源 2.切換語言時不容易出錯
關(guān)于nil,定義為null pointer to object-c class,指的是一個類指針為空,本質(zhì)是(class)0,OC類的字面為零值。
關(guān)于null,定義為null pointer to primitive type or absence of data,指的是一般基礎(chǔ)數(shù)據(jù)類型為空,可以給任意指針賦值,本質(zhì)是(void *)0,是C指針的字面0值。盡量不用null初始化OC對象,null主要針對基礎(chǔ)數(shù)據(jù)類型。
關(guān)于NSNull,包含了唯一方法+(NSNull *)null,是一個對象,用于表示零值的單獨對象。主要用于不能使用nil的場景下,例如可變數(shù)組中,想插入一個空對象時。
(2)objc向一個對象發(fā)送消息[obj foo]和objc_msgSend()函數(shù)之間有什么關(guān)系?????
objc_msgSend()是[obj foo]的具體實現(xiàn)。在動態(tài)編譯時,[obj foo]會被轉(zhuǎn)意為:objc_msgSend(obj, @selector(foo))
先去obj對應(yīng)的類中找方法;找緩存,找不到時去找方法列表;再找父類,以此向上傳遞;最后找不到則轉(zhuǎn)發(fā)。
(3)什么情況會報unrecognized selector異常?
調(diào)用某個對象方法時,當前類中無此方法,那么去父類查找,向上直到NSObject。若依舊找不到,則會報此錯誤。
若沒有實現(xiàn)某個方法時,會調(diào)用_objc_msgForward進行方法轉(zhuǎn)發(fā)。方法對應(yīng)的IMP沒找到,會返回該函數(shù)的IMP去執(zhí)行。
在崩潰前,objc運行時會給出三次拯救崩潰的機會。
+(bool)resolveInstanceMethod:(sel){
//第一次找不到時,會自動調(diào)用該方法,用來給程序添加一個新方法并執(zhí)行
}
-(id)forwardingTargetForselector:(sel)aselctor{
//當系統(tǒng)調(diào)用上一個方法后未能實現(xiàn)添加新方法,這是系統(tǒng)提供一個將SEL轉(zhuǎn)給其他對象的機會
}
(NSMethodSigature *)methodSignatrueForseletor:(sel)aselector{
//當上一個方法返回nil或self時,進入該方法,返回一個方法簽名,并由forwardInvocation:去執(zhí)行
}
-(void)forwardInvocation:(NSInvocation *)anInvocation{
//若上面方法不返回nil,則在這里調(diào)用自己對象的其他方法,也可以調(diào)用其它函數(shù),以及多個不同對象的多個方法
}
(5)一個objc對象如何進行內(nèi)存布局?(有父類時)
所有的父類成員變量以及自己的都會存放在對象所對應(yīng)的存儲空間中
每個對象都有一個isa指針,指向他的類對象,類對象中存放著本身對象的方法列表;成員變量的列表;屬性列表。類對象內(nèi)容也有一個isa指針指向元對象,元對象內(nèi)部存放的是類方法列表,類對象有一個superclass指針,指向父類對象。
根對象是NSObject,superclass指針指向nil
類對象也是實例,也有一個isa指針指向他的元類,即類對象的元類實例,元類內(nèi)部存放的是類方法列表,根元類的isa指針指向自己,superclass指針指向NSObject類。
(6)_objc_msgForward函數(shù)作用,直接調(diào)用將會發(fā)生什么?
當對象沒有實現(xiàn)某個方法時,會調(diào)用該函數(shù)進行方法轉(zhuǎn)發(fā)。
直接調(diào)用該方法,就算實現(xiàn)了要調(diào)用的方法,也不會被調(diào)用,會直接走消息轉(zhuǎn)發(fā)步驟
轉(zhuǎn)發(fā)自http://www.itdecent.cn/p/38f013075e9a