現(xiàn)在網(wǎng)上講解的objc_class 絕大部分是錯(cuò)的巡扇。18年扭仁、19年依然很多童鞋寫著錯(cuò)誤的Runtime文章發(fā)到網(wǎng)上,面試的時(shí)候基本絕大部分人都說著網(wǎng)上所謂的“正確答案”厅翔。
一乖坠、錯(cuò)誤一:
講Runloop首先要講的是objc_class,如圖:
然后就開始講objc_class里的super_class表示父類刀闷。熊泵。。
1甸昏、我們仔細(xì)看上圖顽分,其中有:
#if !__OBJC2__
在2006年7月WWDC中,Apple發(fā)布了“Objective-C 2.0”施蜜。2.0有很多的語法改進(jìn)卒蘸、runtime改進(jìn)、垃圾回收機(jī)制(已廢棄)翻默、支持64 等缸沃。
上面“!OBJC2” 之間的代碼是Objective-C 2.0之前1.0版本的東西恰起。2.0已經(jīng)不支持了。
2和泌、中間還有:
OBJC2_UNAVAILABLE
這句是表示Objective-C 2.0不用使用了村缸。
3、我們從源代碼看下這些定義武氓。
我們可以下載objc4的源代碼。
github上也有源代碼仇箱,不過版本偏老县恕。所以我們還是以opensource.apple.com的為準(zhǔn)。
當(dāng)前最新版本是objc4-750.1剂桥。
3.1忠烛、先看下OBJC2_UNAVAILABLE的定義:
先看注釋:
/* OBJC2_UNAVAILABLE: unavailable in objc 2.0, deprecated in Leopard */
OBJC2_UNAVAILABLE 在objc 2.0中不可用,在Leopard中棄用(不建議使用权逗,但是還可以用)美尸。Leopard是2006年WWDC公開的Mac OS 系統(tǒng)版本。
再看里面的代碼:
#if !defined(OBJC2_UNAVAILABLE)
判斷OBJC_ISA_AVAILABILITY這個(gè)宏是否被定義過斟薇, 如果沒有定義過师坎, 就執(zhí)行執(zhí)行隨后的語句。
我們搜索開源的文件堪滨,沒有查到它在其他地方定義胯陋,所以這里就算是它的定義了。
define OBJC2_UNAVAILABLE UNAVAILABLE_ATTRIBUTE
UNAVAILABLE_ATTRIBUTE 表示不可用袱箱。如果老方法不可用遏乔,還不想刪除,可以用這個(gè)來修飾:
- (void)testMethod UNAVAILABLE_ATTRIBUTE { }
這樣之前調(diào)用該方法的地方都會(huì)報(bào)錯(cuò)发笔。
3.2盟萨、我們?cè)倏聪?strong>OBJC_ISA_AVAILABILITY 的定義:
我們看objc-api.h文件:
通過上面代碼可以看到OBJC_ISA_AVAILABILITY在OC2.0里不建議使用(還可以用)。
我們?cè)倩氐絼傞_始:
網(wǎng)上很多文章講解的圖片下面代碼 實(shí)際上并不是對(duì)的了讨。因?yàn)樗鼈儽旧碓缇蜎]用了捻激。
二、錯(cuò)誤二:
有的文章發(fā)現(xiàn)了上面的問題量蕊,于是根據(jù)上圖 講的是objc_class 里只有Class isa 铺罢。其實(shí)也是錯(cuò)的。
因?yàn)樗耐暾a是:
我們可以看到最開始的一句是:
#if !OBJC_TYPES_DEFINED
在objc-private.h中定義了OBJC_TYPES_DEFINED:
#define OBJC_TYPES_DEFINED 1
所以 #if !OBJC_TYPES_DEFINED 里的代碼是無效的残炮。大家看到的都是假象韭赘。
三、objc_object的錯(cuò)誤
同樣势就,網(wǎng)上講objc_object基本都是根據(jù)代碼:
struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
其實(shí)他們的完整的定義是:
同樣用 #if !OBJC_TYPES_DEFINED 來標(biāo)記這塊代碼是無效的泉瞻。
四脉漏、objc_class的真實(shí)定義
實(shí)際的代碼我們可以從objc-runtime-new.h中看到:
上面截圖代碼不全,大家想看全部代碼可以下載objc-runtime-new.h文件袖牙。