簡介:
在Objective-C語言中,每一個地方我們都在面對類與對象,比如說一個控件、一個字符串、一張圖片、包括我們所說的NSObject等等都可以看做對象,那么Objective-C的類呢也就是所謂的Class,Class也是一個對象,稱為類對象,既然無論何時何地面對對象,哈哈那么你對你的對象了解多少呢?是不是又開始想淫蕩的去研究一下???
正文:
類與對象在Objective-C中算是非常基本的東西,可以說無時無刻不遇到,創建的任何東西都可以認為是一個對象,在無時無刻的不創建類,那么接下來我們將簡單探討一下類與對象
首先來看一下class與object在Objective-C的定義,路徑為/usr/include/objc/objc.h:
typedef struct objc_class *Class;//一個不透明含糊的類型,表示一個Objective-C類
typedef struct objc_object {//表示類的實例
Class isa;
} *id;//指向類實例的指針
我們可以看到Class是一個objc_class結構類型的指針,文件中注釋為An opaque type that represents an Objective-C class;id(任意對象)是一個objc_object結構類型的指針,文件中注釋為A pointer to an instance of a class;
以下是objc_class結構體的一個體現,這里我們來挨個注釋:
struct objc_class
{
struct objc_class* isa;
struct objc_class* super_class;
const char* name;
long version;
long info;
long instance_size;
struct objc_ivar_list* ivars;
struct objc_method_list** methodLists;
struct objc_cache* cache;
struct objc_protocol_list* protocols;
};
isa指針:是一個類型為objc_class指針,是的和class是一個類型的指針,那么我們是不是可以這樣說:一個以objc_class指針指向的所有東西都可以當作一個objc對象來對待
super_class:父類,那么我們知道所有的類都繼承于NSObject或者NSProxy,那么NSObject是所有類的父類嘮,那NSObject或者NSProxy的super_class是什么呢,我們可以直接從項目直接打印下試試看!
NSLog(@"%@",NSObject.superclass);?
2017-10-09 16:32:56.195134+0800 MetaClass[17818:4363641] (null)
由此可見如果一個類的根類為NSObject或者NSProxy,那么這個類的super_class為我們打印的值為null
在《深入淺出Cocoa教程》中提到
好,先中斷一下其他類結構成員的介紹,讓我們理清一下在繼承層次中,子類,父類,根類(這些都是普
通class)以及其對應的metaclass的isa與super_class之間關系:
規則一:類的實例對象的isa指向該類;該類的isa指向該類的metaclass;
規則二:類的super_class指向其父類,如果該類為根類則值為NULL;
規則三:metaclass的isa指向根metaclass,如果該metaclass是根metaclass則指向自身;
規則四:metaclass的super_class指向父metaclass,如果該metaclass是根metaclass則指向
該metaclass對應的類;
如果一個類的跟類為NSObject或者NSProxy那么是不是可以把她的super_class理解為他自己本身呢?
name:const char* name;一個c類型的字符串,用來表示類的名字
在運行時可以通過方法id objc_getClass(const char *aClassName)來得到這個類的名字,通過id objc_getMetaClass(const
char *aClassName)來得到該類的metaclass
version:版本信息,初始默認值為0
當然也可以在運行時通過方法class_setVersion修改版本信息,通過class_getVersion來得到版本信息
info:此處同樣來引用《深入淺出Cocoa教程》中的解讀:
供運行期使用的一些位標識。有如下一些位掩碼:
CLS_CLASS (0x1L)表示該類為普通class,其中包含實例方法和變量;
CLS_META (0x2L)表示該類為metaclass,其中包含類方法;
CLS_INITIALIZED (0x4L)表示該類已經被運行期初始化了,這個標識位只被objc_addClass所設置;CLS_POSING (0x8L)表示該類被pose成其他的類;(poseclass在ObjC 2.0中被廢棄了);CLS_MAPPED (0x10L)為ObjC運行期所使用
CLS_FLUSH_CACHE (0x20L)為ObjC運行期所使用
CLS_GROW_CACHE (0x40L)為ObjC運行期所使用
CLS_NEED_BIND (0x80L)為ObjC運行期所使用
CLS_METHOD_ARRAY (0x100L)該標志位指示methodlists是指向一個objc_method_list還是
一個包含objc_method_list指針的數組;
instance_size:這個類實例變量的大小,內包含了從父類繼承下來的實例變量
ivars:可以看出這個是一個指向objc_ivar_list類型的指針,用處呢是用來存儲每一個實例變量的地址
methodLists:此處和info的解讀方式一樣,參考《深入淺出Cocoa教程》,講的很不錯
與info的一些標志位有關,CLS_METHOD_ARRAY標識位決定其指向的東西(是指向單個objc_method_list還是一個objc_method_list指針數組),如果info設置了CLS_CLASS則objc_method_list存儲實例方法,如果設置的是CLS_META則存儲類方法;
cache:同樣道理指向objc_cache的指針,cache可以看出這個是一個緩存相關的,那么用來緩存什么呢,這就是用來存儲最近使用方法的一個東西,來提高效率,優化
protocols:當然可以看出這一個objc_protocol_list的指針,用來存儲聲明遵守的正式協議
總結:
Objective-C,每一個地方我們都在面對類與對象,很明顯的可以看出Objective-C提供了運行時期限來創造定義objc_class數據結構的機會,從蘋果給我們的一些機制解釋或者方法上可以靈活的運用與處理,有興趣一起交流學習的小伙伴,歡迎加入技術交流q群:150731459,一起進步!共同努力!有理解不正確和不合適的地方換歡迎大家指出,互相學習!
最后送出分享幾句話:
當交流有矛盾的時候一定要及時溝通,假如來說兩個人有矛盾一定要兩個人單獨在一起談,謙卑,理解,放下心態談通了為止!
有一句話叫三人行必有我師,話糙理不糙,互相學習,共同進步!一起加油吧!