iOS Runtime系列一、objc

現在網上講解的objc_class 絕大部分是錯的。18年、19年依然很多童鞋寫著錯誤的Runtime文章發到網上,面試的時候基本絕大部分人都說著網上所謂的“正確答案”。

一、錯誤一:

講Runloop首先要講的是objc_class,如圖:


iOS Runtime系列一、objc_class深深的誤解

objc_class


然後就開始講objc_class裡的super_class表示父類。。。

1、我們仔細看上圖,其中有:

#if !__OBJC2__

在2006年7月WWDC中,Apple發佈了“Objective-C 2.0”。2.0有很多的語法改進、runtime改進、垃圾回收機制(已廢棄)、支持64 等。

上面“!OBJC2” 之間的代碼是Objective-C 2.0之前1.0版本的東西。2.0已經不支持了。

2、中間還有:

OBJC2_UNAVAILABLE

這句是表示Objective-C 2.0不用使用了。

3、我們從源代碼看下這些定義。

我們可以下載objc4的源代碼。

github上也有源代碼,不過版本偏老。所以我們還是以opensource.apple.com的為準。

當前最新版本是objc4-750.1。

3.1、先看下OBJC2_UNAVAILABLE的定義:


iOS Runtime系列一、objc_class深深的誤解

OBJC2_UNAVAILABLE的定義


先看註釋:

/* OBJC2_UNAVAILABLE: unavailable in objc 2.0, deprecated in Leopard */

OBJC2_UNAVAILABLE 在objc 2.0中不可用,在Leopard中棄用(不建議使用,但是還可以用)。Leopard是2006年WWDC公開的Mac OS 系統版本。

再看裡面的代碼:

#if !defined(OBJC2_UNAVAILABLE)

判斷OBJC_ISA_AVAILABILITY這個宏是否被定義過, 如果沒有定義過, 就執行執行隨後的語句。

我們搜索開源的文件,沒有查到它在其他地方定義,所以這裡就算是它的定義了。

define OBJC2_UNAVAILABLE UNAVAILABLE_ATTRIBUTE

UNAVAILABLE_ATTRIBUTE 表示不可用。如果老方法不可用,還不想刪除,可以用這個來修飾:

- (void)testMethod UNAVAILABLE_ATTRIBUTE { }

這樣之前調用該方法的地方都會報錯。

3.2、我們再看下

OBJC_ISA_AVAILABILITY 的定義:

我們看objc-api.h文件:


iOS Runtime系列一、objc_class深深的誤解

OBJC_ISA_AVAILABILITY的定義


通過上面代碼可以看到OBJC_ISA_AVAILABILITY在OC2.0裡不建議使用(還可以用)。

我們再回到剛開始:


iOS Runtime系列一、objc_class深深的誤解

objc_class


網上很多文章講解的圖片下面代碼 實際上並不是對的。因為它們本身早就沒用了。

二、錯誤二:

有的文章發現了上面的問題,於是根據上圖 講的是objc_class 裡只有Class isa 。其實也是錯的。

因為它的完整代碼是:


iOS Runtime系列一、objc_class深深的誤解

完整代碼


我們可以看到最開始的一句是:

#if !OBJC_TYPES_DEFINED

在objc-private.h中定義了OBJC_TYPES_DEFINED:

#define OBJC_TYPES_DEFINED 1

所以 #if !OBJC_TYPES_DEFINED 裡的代碼是無效的。大家看到的都是假象。

三、objc_object的錯誤

同樣,網上講objc_object基本都是根據代碼:

struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};

其實他們的完整的定義是:


iOS Runtime系列一、objc_class深深的誤解

objc_object


同樣用 #if !OBJC_TYPES_DEFINED 來標記這塊代碼是無效的。

四、objc_class的真實定義

實際的代碼我們可以從objc-runtime-new.h中看到:


iOS Runtime系列一、objc_class深深的誤解

objc_class的定義


上面截圖代碼不全,大家想看全部代碼可以下載objc-runtime-new.h文件。

五、objc_object的真實定義

詳見objc-private.h文件


iOS Runtime系列一、objc_class深深的誤解

objc_object的定義


iOS Runtime系列一、objc_class深深的誤解


分享到:


相關文章: