Class定義
Class是一個objc_class * 類型結構體指針
objc_class *是Objective-C2.0版本已經廢除
在Objective-C2.0版本中,使用Class替代objc_class *
//在objc/objc.h系統文件中定義如下
typedef struct objc_class *Class;
objc_class結構體定義
理解時出現小坑.下面的定義才是2.0版本的正解
網上的博客好多都是直接截取以這個來解釋了,但是我看了OBJC_ISA_AVAILABILITY宏定義(下面有代碼片段)之后,無法理解,為什么都說廢除了,但是網上的博客好多都按照廢除的那個來解釋呢?
然后繼續查資料然后在Objective-C的runtime機制01-數據結構和內部關系圖找到了一個合理的解釋.
(其實不用懷疑,確實是2.0版本已廢除了,但是網上的博客好多都按照廢除的那個來解釋)
/// 在objc/runtime.h系統文件中定義如下
struct objc_class {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class _Nullable super_class OBJC2_UNAVAILABLE;
const char * _Nonnull name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE;
struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE;
struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE;
struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */
1、OBJC_ISA_AVAILABILITY 這里標明了已經在Objective-C2.0版本廢除了,但網上的大部分還是直接這個來解釋
用來標記isa對象是否過期或有效如果是Objective-C2.0版本,就表示廢棄,否則就是依然有效.
如果是__OBJC2__版本(Objective-C第二版本),定義OBJC_ISA_AVAILABILITY為 attribute((deprecated))過期標記,否則就依然有效
//在objc/objc-api.h中
/* OBJC_ISA_AVAILABILITY: `isa` will be deprecated or unavailable
* in the future */
#if !defined(OBJC_ISA_AVAILABILITY)
# if __OBJC2__
# define OBJC_ISA_AVAILABILITY __attribute__((deprecated))
# else
# define OBJC_ISA_AVAILABILITY /* still available */
# endif
#endif
2、!OBJC2
表示非Object c 2.0的版本,Object c是從1.0發展到現在的2.0,這個聲明是為了兼容1.0的Object c,若是Object c 2.0的話,可見objc_class與objc_object的定義是一樣的,都是只有一個isa指針,所以說在Object c里面,類也是一個對象
objc_class結構體定義
下面??這個是蘋果官網的源碼片段objc4-680,objc_class結構體定義在OC的2.0版本定義
//-------- [file:objc-runtime-new.h] --------
struct objc_class : objc_object {
// Class ISA;
Class superclass;
cache_t cache; // formerly cache pointer and vtable
class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags
......
}
//-------- [file:objc-private.h] --------
typedef struct objc_class *Class;
typedef struct objc_object *id;
struct objc_object {
private:
isa_t isa;
......
}
union isa_t
{
......
Class cls;
uintptr_t bits;
......
}
作者:qiushuitian
鏈接:http://www.lxweimin.com/p/50f2bcfc8fb7
- objc_object與 objc_class關系
Runtime中定義了一個叫做 objc_object 的結構體,代表OC層的對象
定義了一個objc_class的結構體,代表OC層的類,可以清楚看到, objc_class是繼承objc_object的,因此,類也是一個objc_object的對象
- objc_object中的成員變量isa
objc_object中有個isa_t 的成員變量isa,isa_t是個聯合體,我們只關心它的Class cls的聯合部分。而Class又是個objc_class *。每個對象里面有個isa的成員變量,指向它代表一個類的東西。從OC的角度看,每個對象都能從isa中尋找到它的類的相關信息。
類與元類
1.類對象(class object)
編譯器會知道類的各種信息,如類名,類屬性,類方法等等,然后在運行時,編譯器會根據類描述信息進行生成類對象(class object),這個對象是描述類信息的,是一個單例對象(singleton),這個好理解.因為整個生命周期內唯一一個類
2.元類對象(metaclass object):
類對象既然是objc_object類型,當然也有個isa的指針.這個isa指針指向的對象就是元類對象(metaclass object)。元類對象存儲的信息描述的是類對象的其中虛線 isa指針,實線superclass
靜態描述圖
isa指針指向圖例
程序啟動之后,會根據編譯時的類的信息,在runtime環境中構建相應的類對象和元類對象。
元類對象isa都指向根類,類對象的isa指向自己的元類對象,并且是個單例,構建相應的superclass等。這樣,啟動之后,runtime就知道有些啥類,他們能干嘛,他們之間的關系是什么樣了。
運行時,如果遇到創建OC某個類的實例對象(instance object),分配空間之后,把isa指針指向對象的類對象(class object),這樣,對于這個OC對象,也就能知道類的信息。
為啥搞得那么復雜
C語言不是動態語言。OC作為C的超集,要實現動態,就要把類的描述之類的東西從編譯階段挪到運行階段。那么在運行階段,就需要有類對象(class object),元類對象(metaclass object)等等對象化的東西來處理OC類的信息。runtime就這么玩的。
參考博客:
1、Objective-C的runtime機制01-數據結構和內部關系圖[推薦閱讀]
2、iOS底層原理總結 - 探尋OC對象的本質[推薦閱讀]
3、iOS Class結構分析