在 Objective-C 中向 nil 發(fā)送消息是完全有效的——只是在運(yùn)行時(shí)不會(huì)有任何作用:
如果一個(gè)方法返回值是一個(gè)對(duì)象,那么發(fā)送給nil的消息將返回0(nil)部默。例如:
Person* motherInlaw =[[aPerson spouse]mother];
如果 spouse 對(duì)象為 nil,那么發(fā)送給 nil 的消息 mother 也將返回 nil造虎。
如果方法返回值為指針類型傅蹂,其指針大小為小于或者等于sizeof(void*),float,double份蝴,long double 或者 long long 的整型標(biāo)量犁功,發(fā)送給 nil 的消息將返回0。
如果方法返回值為結(jié)構(gòu)體,發(fā)送給 nil 的消息將返回0婚夫。結(jié)構(gòu)體中各個(gè)字段的值將都是0波桩。
如果方法的返回值不是上述提到的幾種情況,那么發(fā)送給 nil 的消息的返回值將是未定義的请敦。
具體原因如下:
objc是動(dòng)態(tài)語言镐躲,每個(gè)方法在運(yùn)行時(shí)會(huì)被動(dòng)態(tài)轉(zhuǎn)為消息發(fā)送,即:objc_msgSend(receiver, selector)侍筛。
那么萤皂,為了方便理解這個(gè)內(nèi)容,還是貼一個(gè)objc的源代碼:
// runtime.h(類在runtime中的定義)// http://weibo.com/luohanchenyilong/// https://github.com/ChenYilongstructobjc_class{Class isa OBJC_ISA_AVAILABILITY;//isa指針指向Meta Class匣椰,因?yàn)镺bjc的類的本身也是一個(gè)Object裆熙,為了處理這個(gè)關(guān)系,runtime就創(chuàng)造了Meta Class禽笑,當(dāng)給類發(fā)送[NSObject alloc]這樣消息時(shí)入录,實(shí)際上是把這個(gè)消息發(fā)給了Class Object#if!__OBJC2__Class super_class OBJC2_UNAVAILABLE;// 父類constchar*name OBJC2_UNAVAILABLE;// 類名longversion OBJC2_UNAVAILABLE;// 類的版本信息,默認(rèn)為0longinfo OBJC2_UNAVAILABLE;// 類信息佳镜,供運(yùn)行期使用的一些位標(biāo)識(shí)longinstance_size OBJC2_UNAVAILABLE;// 該類的實(shí)例變量大小structobjc_ivar_list*ivarsOBJC2_UNAVAILABLE;// 該類的成員變量鏈表structobjc_method_list**methodListsOBJC2_UNAVAILABLE;// 方法定義的鏈表structobjc_cache*cacheOBJC2_UNAVAILABLE;// 方法緩存僚稿,對(duì)象接到一個(gè)消息會(huì)根據(jù)isa指針查找消息對(duì)象,這時(shí)會(huì)在method Lists中遍歷蟀伸,如果cache了蚀同,常用的方法調(diào)用時(shí)就能夠提高調(diào)用的效率。structobjc_protocol_list*protocolsOBJC2_UNAVAILABLE;// 協(xié)議鏈表#endif} OBJC2_UNAVAILABLE;
objc在向一個(gè)對(duì)象發(fā)送消息時(shí)啊掏,runtime庫會(huì)根據(jù)對(duì)象的isa指針找到該對(duì)象實(shí)際所屬的類蠢络,然后在該類中的方法列表以及其父類方法列表中尋找方法運(yùn)行,然后在發(fā)送消息的時(shí)候迟蜜,objc_msgSend方法不會(huì)返回值刹孔,所謂的返回內(nèi)容都是具體調(diào)用時(shí)執(zhí)行的。那么娜睛,回到本題髓霞,如果向一個(gè)nil對(duì)象發(fā)送消息,首先在尋找對(duì)象的isa指針時(shí)就是0地址返回了微姊,所以不會(huì)出現(xiàn)任何錯(cuò)誤酸茴。
作者:啟發(fā)禪悟
鏈接:http://www.reibang.com/p/b7cda433e4f5
來源:簡書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)兢交,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處薪捍。