iOS開(kāi)發(fā)基礎(chǔ)性知識(shí)(十二)----iOS底層數(shù)據(jù)結(jié)構(gòu)

一遣鼓、類(lèi)的數(shù)據(jù)結(jié)構(gòu)

Class(指針)

typedef struct objc_class *Class;

/*

這是由編譯器為每個(gè)類(lèi)產(chǎn)生的數(shù)據(jù)結(jié)構(gòu),這個(gè)結(jié)構(gòu)定義了一個(gè)類(lèi).這個(gè)結(jié)構(gòu)是通過(guò)編譯器在執(zhí)行時(shí)產(chǎn)生,在運(yùn)行時(shí)發(fā)送消息時(shí)使用.因此,一些成員改變了類(lèi)型.編譯器產(chǎn)生"char* const"類(lèi)型的字符串指針替代了下面的成員變量"super_class"

*/

struct objc_class {

struct objc_class*? class_pointer;? ? /* 指向元類(lèi)的指針. */

struct objc_class*? super_class;? ? ? /* 指向父類(lèi)的指針. 對(duì)于NSObject來(lái)說(shuō)是NULL.*/

const char*? ? ? ? name;? ? ? ? ? ? /* 類(lèi)的名稱(chēng). */

long? ? ? ? ? ? ? ? version;? ? ? ? ? /* 未知. */

unsigned long? ? ? info;? ? ? ? ? ? /* 比特蒙板.? 參考下面類(lèi)的蒙板定義. */

long? ? ? ? ? ? ? ? instance_size;? ? /* 類(lèi)的字節(jié)數(shù).包含類(lèi)的定義和所有父類(lèi)的定義 */

#ifdef _WIN64

long pad;

#endif

struct objc_ivar_list* ivars;? ? ? ? /* 指向類(lèi)中定義的實(shí)例變量的列表結(jié)構(gòu). NULL代表沒(méi)有實(shí)例變量.不包括父類(lèi)的變量. */

struct objc_method_list*? methods;? ? /* 鏈接類(lèi)中定義的實(shí)例方法. */

struct sarray *? ? dtable;? ? ? ? ? ? /* 指向?qū)嵗椒ǚ峙浔? */

struct objc_class* subclass_list;? ? /* 父類(lèi)列表 */

struct objc_class* sibling_class;

struct objc_protocol_list *protocols; /* 要實(shí)現(xiàn)的原型列表 */

void* gc_object_type;

};

Method(指針)

typedef struct objc_method *Method;

/* 編譯器依據(jù)類(lèi)中定義的方法為該類(lèi)產(chǎn)生一個(gè)或更多這種這種結(jié)構(gòu).

一個(gè)類(lèi)的實(shí)現(xiàn)可以分散在一個(gè)文件中不同部分,同時(shí)類(lèi)別可以分散在不同的模塊中.為了處理這個(gè)問(wèn)題,使用一個(gè)單獨(dú)的方法鏈表 */

struct objc_method

{

SEL? ? ? ? method_name;? /* 這個(gè)變量就是方法的名稱(chēng).編譯器使用在這里使用一個(gè)`char*`,當(dāng)一個(gè)方法被注冊(cè),名稱(chēng)在運(yùn)行時(shí)被使用真正的SEL替代? */

const char* method_types; /* 描述方法的參數(shù)列表. 在運(yùn)行時(shí)注冊(cè)選擇器時(shí)使用.那時(shí)候方法名就會(huì)包含方法的參數(shù)列表.*/

IMP? ? ? ? method_imp;? /* 方法執(zhí)行時(shí)候的地址. */

};

Ivar(指針)

typedef struct objc_ivar *Ivar;

/* 編譯器依據(jù)類(lèi)中定義的實(shí)例變量為該類(lèi)產(chǎn)生一個(gè)或更多這種這種結(jié)構(gòu)? */

struct objc_ivar

{

const char* ivar_name;? /* 類(lèi)中定義的變量名. */

const char* ivar_type;? /* 描述變量的類(lèi)型.調(diào)試時(shí)非常有用. */

int? ? ? ? ivar_offset; /* 實(shí)例結(jié)構(gòu)的基地址偏移字節(jié) */

};

Category(指針)

typedef struct objc_category *Category;

/* 編譯器為每個(gè)類(lèi)別產(chǎn)生一個(gè)這樣的結(jié)構(gòu).一個(gè)類(lèi)可以具有多個(gè)類(lèi)別同時(shí)既包括實(shí)例方法,也可以包括類(lèi)方法*/

struct objc_category

{

const char*? category_name;? ? ? ? ? ? ? ? /* 類(lèi)別名.定義在類(lèi)別后面的括號(hào)內(nèi)*/

const char*? class_name;? ? ? ? ? ? ? ? ? /* 類(lèi)名 */

struct objc_method_list? *instance_methods; /* 鏈接類(lèi)中定義的實(shí)例方法. NULL表示沒(méi)有實(shí)例方法. */

struct objc_method_list *class_methods;? ? /* 鏈接類(lèi)中定義的類(lèi)方法. NULL表示沒(méi)有類(lèi)方法. */

struct objc_protocol_list *protocols;? ? ? /* 遵循的協(xié)議表? */

};

objc_property_t

typedef struct objc_property *objc_property_t;

IMP

id (*IMP)(id, SEL, ...)

SEL

typedef struct objc_selector *SEL;

struct objc_selector

{

void *sel_id;

const char *sel_types;

};

objc_method_list

struct objc_method_list

{

struct objc_method_list*? method_next; /* 這個(gè)變量用來(lái)鏈接另一個(gè)單獨(dú)的方法鏈表 */

int? ? ? ? ? ? method_count;? ? ? ? ? ? /* 結(jié)構(gòu)中定義的方法數(shù)量 */

struct objc_method method_list[1];? ? ? /* 可變長(zhǎng)度的結(jié)構(gòu) */

};

objc_cache

struct objc_cache

{

unsigned int mask;

unsigned int occupied;

Method buckets[1];

};

objc_protocol_list

struct objc_protocol_list

{

struct objc_protocol_list *next;

size_t count;

struct objc_protocol *list[1];

};

二衔统、實(shí)例的數(shù)據(jù)結(jié)構(gòu)

id

typedef struct objc_object *id;

objc_object

struct objc_object

{

// 類(lèi)的指針是對(duì)象相關(guān)的類(lèi).如果是一個(gè)類(lèi)對(duì)象, 這個(gè)指針指向元類(lèi).

Class isa;

};

objc_super

struct objc_super

{

id? ? self;? ? ? ? /* 消息的接受者? */

Class super_class; /* 接受者的父類(lèi)? */

};

三、底層-Class詳解(iOS)

? iOS的開(kāi)發(fā)語(yǔ)言objective-c岛都,它的真實(shí)面目是它不是真正的面向?qū)ο笳Z(yǔ)言蚤认,而抽象理解為此而已凹蜈。其實(shí)它就是C+限寞,有個(gè)公式可以很好地詮釋那就是OC = C + Runtime;

? 接下來(lái)我們就好好講講在Runtime下的objc-class忍啸。

3.1Class定義

3.1.1 小小說(shuō)明一下objc-api.h里的OBJC_ISA_AVAILABILITY:

? /*介紹一下attribute((deprecated))的作用,__attribute是給函數(shù)、變量履植、類(lèi)做屬性說(shuō)明的關(guān)鍵字计雌,deprecated是棄用原先的進(jìn)行兼容

? 若是OBJC2,原先的類(lèi),編譯器發(fā)出警告*/

#if !defined(OBJC_ISA_AVAILABILITY)

#? if __OBJC2__

#? ? ? define OBJC_ISA_AVAILABILITY? __attribute__((deprecated))

#? else

#? ? ? define OBJC_ISA_AVAILABILITY? /* still available */

#? endif

#endif

typedef struct objc_method *Method;

typedef struct objc_ivar *Ivar;

typedef struct objc_category *Category;

typedef struct objc_property *objc_property_t;

3.1.2 接下來(lái)就是runtime.h里的Class的定義:

struct objc_class {

Class isa? OBJC_ISA_AVAILABILITY;//每個(gè)Class都有一個(gè)isa指針

#if !__OBJC2__

Class super_class? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;//父類(lèi)

const char *name? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;//類(lèi)名

long version? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;//類(lèi)版本

long info? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;//!*!供運(yùn)行期使用的一些位標(biāo)識(shí)玫霎。如:CLS_CLASS (0x1L)表示該類(lèi)為普通class; CLS_META(0x2L)表示該類(lèi)為metaclass等(runtime.h中有詳細(xì)列出)

long instance_size? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;//實(shí)例大小

struct objc_ivar_list *ivars? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;//存儲(chǔ)每個(gè)實(shí)例變量的內(nèi)存地址

struct objc_method_list **methodLists? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;//!*!根據(jù)info的信息確定是類(lèi)還是實(shí)例凿滤,運(yùn)行什么函數(shù)方法等

struct objc_cache *cache? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;//緩存

struct objc_protocol_list *protocols? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;//協(xié)議

#endif

} OBJC2_UNAVAILABLE;

四、class初始化

? Runtime的行為之一就是initialize庶近。在程序運(yùn)行過(guò)程中翁脆,它會(huì)在你程序中每個(gè)類(lèi)調(diào)用一次initialize。這個(gè)調(diào)用的時(shí)間發(fā)生在你的類(lèi)接收到消息之前鼻种,但是在它的超類(lèi)接收到initialize之后反番。

//在蘋(píng)果的官方Runtime中有個(gè)objc-initialize.m文件,進(jìn)行解讀

typedef struct _objc_initializing_classes {

int classesAllocated;//類(lèi)是否分配存在

Class *metaclasses;//類(lèi)的父類(lèi),如果沒(méi)有父類(lèi)那就是自身

}

_objc_initializing_classes;//初始化一個(gè)對(duì)象_objc_initializing_classes

//將所有的類(lèi)存儲(chǔ)在靜態(tài)鏈表中叉钥,以待接下來(lái)的接收和發(fā)送消息

static _objc_initializing_classes *_fetchInitializingClassList(BOOL create)

{

_objc_pthread_data *data;

//list為類(lèi)鏈表

_objc_initializing_classes *list;

Class *classes;

data = _objc_fetch_pthread_data(create);

if (data == nil) return nil;

//鏈表增加類(lèi)節(jié)點(diǎn)

list = data->initializingClasses;

if (list == nil) {

if (!create) {

return nil;

} else {

list = (_objc_initializing_classes *)

_calloc_internal(1, sizeof(_objc_initializing_classes));

data->initializingClasses = list;

}}//將創(chuàng)建的classes接在metaclasses后

classes = list->metaclasses;

if (classes == nil) {

// If _objc_initializing_classes exists, allocate metaclass array,

// even if create == NO.

// Allow 4 simultaneous class inits on this thread before realloc.

list->classesAllocated = 4;

classes = (Class *)

_calloc_internal(list->classesAllocated, sizeof(Class));

list->metaclasses = classes;

}return list;

}

五罢缸、runtime下Class的各項(xiàng)操作(重要幾個(gè))

5.1 add*(增加)

5.1.1 static IMP addMethod(Class cls, SEL name, IMP imp, const char *types, BOOL replace);//增加方法

5.1.2 BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types);//增加類(lèi)方法

5.1.3 BOOL class_addIvar(Class cls, const char *name, size_t size,uint8_t alignment, const char *type);//增加實(shí)例變量

5.1.4 static BOOL _class_addProperty(Class cls, const char *name,const objc_property_attribute_t *attrs, unsigned int count,BOOL replace);//增加屬性

5.2 replace*(修改)

5.2.1 IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types); //修改方法

5.2.2 void class_replaceProperty(Class cls, const char *name,const objc_property_attribute_t *attrs, unsigned int n);//修改屬性

5.3 get*(獲取)

5.3.1 static Class getClass(const char *name);//獲取類(lèi)

5.3.2 static ivar_t *getIvar(Class cls, const char *name);//獲取類(lèi)變量(static相當(dāng)于“+“)

5.3.3 Method class_getInstanceMethod(Class cls, SEL sel);//獲取實(shí)例方法

5.3.4 static Method _class_getMethod(Class cls, SEL sel);;//獲取類(lèi)方法

5.3.5 static Protocol *getProtocol(const char *name);//增加協(xié)議

5.4 set*(設(shè)置)

5.4.1 objc_class::setInitialized();//set的initialized初始化

5.4.2 static Class setSuperclass(Class cls, Class newSuper);//設(shè)置父類(lèi)

5.5 其他還有類(lèi)似于 void *objc_destructInstance(id obj);//摧毀實(shí)例對(duì)象等等

六、Class的重要函數(shù)

6.1 get*(獲取)

6.1.1 object_getClass(id obj);

6.1.2 IMP object_getMethodImplementation(id obj, SEL name);//獲得實(shí)例方法實(shí)現(xiàn)

6.1.3 Ivar object_getInstanceVariable(id obj, const char *name, void **value)//獲取實(shí)例屬性

6.2 set*(設(shè)置)

6.2.1 Class object_setClass(id obj, Class cls);

6.2.2 Ivar object_setInstanceVariable(id obj, const char *name, void *value);//設(shè)置實(shí)例屬性

6.2.3 void object_setIvar(id obj, Ivar ivar, id value);//設(shè)置實(shí)例變量

6.3 其他

6.3.1 static void _class_resolveClassMethod(Class cls, SEL sel, id inst);//動(dòng)態(tài)添加類(lèi)方法投队,不必在乎方法是否存在

6.3.2 static void _class_resolveInstanceMethod(Class cls, SEL sel, id inst);//動(dòng)態(tài)添加實(shí)現(xiàn)方法枫疆,不必在乎方法是否存在

6.3.3 unsigned _class_createInstancesFromZone(Class cls, size_t extraBytes, void *zone,id *results, unsigned num_requested);//創(chuàng)建實(shí)例存儲(chǔ)空間

6.4 消息轉(zhuǎn)發(fā)

6.4.1 void? ? instrumentObjcMessageSends(BOOL flag);//flag傳入YES,運(yùn)行時(shí)發(fā)送的所有消息都會(huì)打印到/tmp/msgSend-xxxx文件里了敷鸦。



站在巨人的肩膀上才有這些總結(jié)

菜鳥(niǎo)走向大牛养铸,大家共同前進(jìn),如果覺(jué)得不錯(cuò)轧膘,請(qǐng)給個(gè)贊/關(guān)注。

一起交流學(xué)習(xí)兔甘,有問(wèn)題隨時(shí)歡迎聯(lián)系谎碍,郵箱:383708669@qq.com

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市洞焙,隨后出現(xiàn)的幾起案子蟆淀,更是在濱河造成了極大的恐慌,老刑警劉巖澡匪,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件熔任,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡唁情,警方通過(guò)查閱死者的電腦和手機(jī)疑苔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)甸鸟,“玉大人惦费,你說(shuō)我怎么就攤上這事兵迅。” “怎么了薪贫?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵恍箭,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我瞧省,道長(zhǎng)扯夭,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任鞍匾,我火速辦了婚禮交洗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘候学。我一直安慰自己藕筋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布梳码。 她就那樣靜靜地躺著隐圾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪掰茶。 梳的紋絲不亂的頭發(fā)上暇藏,一...
    開(kāi)封第一講書(shū)人閱讀 52,262評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音濒蒋,去河邊找鬼盐碱。 笑死,一個(gè)胖子當(dāng)著我的面吹牛沪伙,可吹牛的內(nèi)容都是我干的瓮顽。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼围橡,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼暖混!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起翁授,我...
    開(kāi)封第一講書(shū)人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤拣播,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后收擦,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體贮配,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年塞赂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了泪勒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖酣藻,靈堂內(nèi)的尸體忽然破棺而出曹洽,到底是詐尸還是另有隱情,我是刑警寧澤辽剧,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布送淆,位于F島的核電站,受9級(jí)特大地震影響怕轿,放射性物質(zhì)發(fā)生泄漏偷崩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一撞羽、第九天 我趴在偏房一處隱蔽的房頂上張望阐斜。 院中可真熱鬧,春花似錦诀紊、人聲如沸谒出。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)笤喳。三九已至,卻和暖如春碌宴,著一層夾襖步出監(jiān)牢的瞬間杀狡,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工贰镣, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留呜象,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓碑隆,卻偏偏與公主長(zhǎng)得像恭陡,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子上煤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉子姜,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,725評(píng)論 0 9
  • 我們常常會(huì)聽(tīng)說(shuō) Objective-C 是一門(mén)動(dòng)態(tài)語(yǔ)言,那么這個(gè)「動(dòng)態(tài)」表現(xiàn)在哪呢楼入?我想最主要的表現(xiàn)就是 Obje...
    Ethan_Struggle閱讀 2,199評(píng)論 0 7
  • //聯(lián)系人:石虎QQ: 1224614774昵稱(chēng):嗡嘛呢叭咪哄 objc_class結(jié)構(gòu)體 一、類(lèi)在OC中是obj...
    石虎132閱讀 2,186評(píng)論 0 21
  • Objective-C語(yǔ)言是一門(mén)動(dòng)態(tài)語(yǔ)言牧抽,它將很多靜態(tài)語(yǔ)言在編譯和鏈接時(shí)期做的事放到了運(yùn)行時(shí)來(lái)處理嘉熊。這種動(dòng)態(tài)語(yǔ)言的...
    有一種再見(jiàn)叫青春閱讀 588評(píng)論 0 3
  • 原文出處:南峰子的技術(shù)博客 Objective-C語(yǔ)言是一門(mén)動(dòng)態(tài)語(yǔ)言,它將很多靜態(tài)語(yǔ)言在編譯和鏈接時(shí)期做的事放到了...
    _燴面_閱讀 1,232評(píng)論 1 5