欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

目錄

柚子快報(bào)激活碼778899分享:iOS——分類、擴(kuò)展和關(guān)聯(lián)對(duì)象

柚子快報(bào)激活碼778899分享:iOS——分類、擴(kuò)展和關(guān)聯(lián)對(duì)象

http://yzkb.51969.com/

前情回顧

回顧一下什么是分類、什么是擴(kuò)展: 分類(Category)和類擴(kuò)展(Extension)是兩種常見(jiàn)的代碼組織方式,用于擴(kuò)展類的功能。

分類(Category)

分類是一種將類的實(shí)現(xiàn)分散到多個(gè)源文件的方式。通過(guò)使用分類,你可以將一個(gè)類的實(shí)現(xiàn)分散到多個(gè)源文件中。分類可以為現(xiàn)有的類添加新的方法,這使得你可以向現(xiàn)有的類添加自己的方法。 分類不能添加實(shí)例變量,只能添加方法。 分類的特性是可以在運(yùn)行時(shí)階段動(dòng)態(tài)的為已有的類添加新行為。 分類就是對(duì)裝飾模式的一種具體實(shí)現(xiàn)。它的主要作用是在不改變?cè)蓄惖那疤嵯拢瑒?dòng)態(tài)地給這個(gè)類添加一些方法。 分類也可以把framework私有方法公開(kāi)化

現(xiàn)在我們通過(guò)源碼看一下分類:

struct _category_t {

const char *name; // 分類的名稱

struct _class_t *cls; // 分類所屬的類

const struct _method_list_t *instance_methods; // 分類中定義的實(shí)例方法列表

const struct _method_list_t *class_methods; // 分類中定義的類方法列表

const struct _protocol_list_t *protocols; // 分類實(shí)現(xiàn)的協(xié)議列表

const struct _prop_list_t *properties; // 分類中定義的屬性列表

};

extern "C" __declspec(dllimport) struct objc_cache _objc_empty_cache;

從結(jié)構(gòu)體可以知道,分類可以添加屬性,但是只會(huì)生成這些屬性的getter和setter方法的聲明,并不會(huì)自動(dòng)實(shí)現(xiàn)這些方法。也就是說(shuō),如果你在分類中添加了一個(gè)屬性,你還需要自己去實(shí)現(xiàn)這個(gè)屬性的getter和setter方法。分類不像類,它沒(méi)有成員變量列表,所以你不能在分類中添加成員變量。分類中的方法可以在運(yùn)行時(shí)動(dòng)態(tài)改變,但結(jié)構(gòu)體不能。如果你想要在運(yùn)行時(shí)給原來(lái)的結(jié)構(gòu)體添加一個(gè)屬性,你只能通過(guò)關(guān)聯(lián)對(duì)象的方式。關(guān)聯(lián)對(duì)象的本質(zhì)是在類的定義之外為類增加額外的存儲(chǔ)空間,實(shí)現(xiàn)了一種映射關(guān)系。

擴(kuò)展(Extension)

類擴(kuò)展與分類類似,有時(shí)候也被稱為匿名分類,但是類擴(kuò)展可以添加實(shí)例變量和屬性。與分類不同,類擴(kuò)展的方法和屬性必須在類的主實(shí)現(xiàn)文件中實(shí)現(xiàn)。擴(kuò)展中聲明的所有方法和屬性必須在主類中實(shí)現(xiàn),否則會(huì)導(dǎo)致編譯錯(cuò)誤。此外,類擴(kuò)展中添加的實(shí)例變量默認(rèn)為@private類型,其使用范圍只能在自身類中。 擴(kuò)展是在編譯階段與該類同時(shí)編譯的,是類的一部分。擴(kuò)展中聲明的方法只能在該類的@implementation中實(shí)現(xiàn)。所以這也就意味著我們無(wú)法對(duì)系統(tǒng)的類使用擴(kuò)展。

分類和擴(kuò)展的區(qū)別

分類原則上只能增加方法,但是也可以通過(guò)關(guān)聯(lián)屬性增加屬性拓展可以增加方法和屬性,都是私有的。擴(kuò)展只能在自身類中使用,而不是子類或者其他地方。類擴(kuò)展是在編譯階段添加到類中,而分類是在運(yùn)行時(shí)添加到類中

關(guān)聯(lián)對(duì)象

在OC中,關(guān)聯(lián)對(duì)象是一種動(dòng)態(tài)給對(duì)象添加屬性的機(jī)制。 正如我們知道的,OC的類可以有實(shí)例變量和屬性,這些都是在編譯時(shí)期就已經(jīng)確定的。然而,有時(shí)候我們可能希望在運(yùn)行時(shí)給對(duì)象動(dòng)態(tài)添加一些屬性,就可以用關(guān)聯(lián)對(duì)象。 關(guān)聯(lián)對(duì)象還可以為分類添加屬性: Category(分類)的底層結(jié)構(gòu)中,沒(méi)有成員變量(ivar),因此不能給分類添加成員變量;在分類里面聲明的屬性,只會(huì)生成 get/set 方法的聲明,沒(méi)有方法的實(shí)現(xiàn),所以我們不能直接給分類添加成員變量,但是可以間接實(shí)現(xiàn),那就是使用關(guān)聯(lián)對(duì)象

關(guān)聯(lián)對(duì)象實(shí)際上是通過(guò)Objective-C的運(yùn)行時(shí)系統(tǒng)實(shí)現(xiàn)的。使用以下三個(gè)函數(shù)來(lái)添加、獲取或者刪除關(guān)聯(lián)對(duì)象:

給對(duì)象添加關(guān)聯(lián)對(duì)象:

void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy)

其中objc_AssociationPolicy policy 是指關(guān)聯(lián)策略。 獲取對(duì)象的關(guān)聯(lián)對(duì)象:

id objc_getAssociatedObject(id object, const void * key)

刪除對(duì)象的所有關(guān)聯(lián)對(duì)象:

void objc_removeAssociatedObjects(id object)

使用方法:

創(chuàng)建ZSXPerson類,以及它的分類ZSXPerson+TextZSXPerson+Text.h中聲明想要添加的屬性ZSXPerson+Text.m中使用關(guān)聯(lián)對(duì)象API實(shí)現(xiàn) get/set 方法

修飾符

關(guān)聯(lián)對(duì)象并不會(huì)改變對(duì)象的類或類的定義,它們只是在運(yùn)行時(shí)環(huán)境中與特定的對(duì)象關(guān)聯(lián)在一起。關(guān)聯(lián)對(duì)象的生命周期與對(duì)象本身的生命周期相同,當(dāng)對(duì)象被銷毀時(shí),其關(guān)聯(lián)的對(duì)象也會(huì)被銷毀。

為分類添加關(guān)聯(lián)對(duì)象的本質(zhì)

關(guān)聯(lián)對(duì)象的本質(zhì)

每一個(gè)對(duì)象的關(guān)聯(lián)對(duì)象實(shí)際上都存儲(chǔ)在AssociationHashMap內(nèi)。所有對(duì)象的關(guān)聯(lián)內(nèi)容都在同一個(gè)全局容器中。 關(guān)聯(lián)對(duì)象由AssociationManager管理并在AssociationHashMap存儲(chǔ)。 所以說(shuō), 假如給分類添加了一個(gè)關(guān)聯(lián)對(duì)象, 那么該關(guān)聯(lián)內(nèi)容既不需要分類管理, 也不是由原類管理。

class AssociationsManager {

static spinlock_t _lock;

static AssociationsHashMap *_map; // associative references: object pointer -> PtrPtrHashMap.

public:

AssociationsManager() { _lock.lock(); }

~AssociationsManager() { _lock.unlock(); }

AssociationsHashMap &associations() {

if (_map == NULL)

_map = new AssociationsHashMap();

return *_map;

}

};

AssociationsHashMap內(nèi)部維護(hù)了一個(gè)ObjectAssociationMap哈希表:

class AssociationsHashMap : public unordered_map {

public:

void *operator new(size_t n) { return ::malloc(n); }

void operator delete(void *ptr) { ::free(ptr); }

};

ObjectAssociationMap內(nèi)部維護(hù)了一個(gè)ObjcAssociation哈希表:

class ObjectAssociationMap : public std::map {

public:

void *operator new(size_t n) { return ::malloc(n); }

void operator delete(void *ptr) { ::free(ptr); }

};

key的常見(jiàn)用法

使用的get方法的@selecor作為key

objc_setAssociatedObject(obj, @selector(getter), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)objc_getAssociatedObject(obj, @selector(getter))

使用指針的地址作為key

static void *MyKey = &MyKey;

objc_setAssociatedObject(obj, MyKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)objc_getAssociatedObject(obj, MyKey)

使用static字符作為key

static char MyKey;

objc_setAssociatedObject(obj, &MyKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)objc_getAssociatedObject(obj, &MyKey)

使用屬性名作為key

objc_setAssociatedObject(obj, @“property”, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);objc_getAssociatedObject(obj, @“property”);

錯(cuò)誤用法舉例

static void *MyKey;

objc_setAssociatedObject(obj, MyKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)objc_getAssociatedObject(obj, MyKey) 如上寫(xiě)法,沒(méi)有給*MyKey,他相當(dāng)于是NULL,這時(shí)候,如果再有另一個(gè)屬性使用Keystatic void *OtherKey;,MyKey和OtherKey都是 NULL,這就相當(dāng)于把多個(gè)屬性都與NULLKey關(guān)聯(lián),明顯就出問(wèn)題了

關(guān)聯(lián)對(duì)象的實(shí)現(xiàn)原理

學(xué)習(xí)OC對(duì)象本質(zhì)時(shí),我們知道對(duì)象實(shí)際被轉(zhuǎn)化成struct ClassName_IMPL結(jié)構(gòu)體,對(duì)象的成員變量的值保存在該結(jié)構(gòu)體中。 使用關(guān)聯(lián)對(duì)象給分類添加的成員變量,他并不是保存在該結(jié)構(gòu)體下,因?yàn)镃ategory的底層結(jié)構(gòu)中并沒(méi)有ivar。 他是存儲(chǔ)在全局的統(tǒng)一的一個(gè)AssociationsManager中。

核心對(duì)象

AssociationsManagerAssociationsHashMapObjectAssociationMapObjcAssociation

下面來(lái)看它們之間的關(guān)系:

AssociationsManager

AssociationsManager 是管理所有關(guān)聯(lián)對(duì)象的中心管理器。它負(fù)責(zé)存儲(chǔ)和檢索關(guān)聯(lián)對(duì)象的整體結(jié)構(gòu)。它是一個(gè)單例,確保在整個(gè)運(yùn)行時(shí)環(huán)境中只有一個(gè)實(shí)例。

職責(zé):管理和維護(hù)所有對(duì)象的關(guān)聯(lián)數(shù)據(jù)。

AssociationsHashMap

AssociationsHashMap 是一個(gè)哈希表,用于將對(duì)象映射到它們的關(guān)聯(lián)數(shù)據(jù)。它在內(nèi)部使用了一個(gè)哈希表,這個(gè)字段的 key 是被添加關(guān)聯(lián)對(duì)象的對(duì)象的地址,value 是個(gè)ObjectAssociationMap

職責(zé):高效地查找和存儲(chǔ)對(duì)象與其關(guān)聯(lián)數(shù)據(jù)之間的映射。

ObjectAssociationMap

ObjectAssociationMap 是一個(gè)結(jié)構(gòu)體或類,用于存儲(chǔ)單個(gè)對(duì)象的所有關(guān)聯(lián)數(shù)據(jù)。key 是我們調(diào)用objc_setAssociatedObject時(shí)傳入的 key,value 是ObjectAssociation

職責(zé):管理一個(gè)對(duì)象的所有關(guān)聯(lián)鍵及其對(duì)應(yīng)的關(guān)聯(lián)值。

ObjcAssociation

ObjcAssociation 是具體的關(guān)聯(lián)對(duì)象,包含實(shí)際的數(shù)據(jù)以及數(shù)據(jù)的存儲(chǔ)策略,_policy是我們?cè)O(shè)置的修飾符(比如:OBJC_ASSOCIATION_ASSIGN),_value是我們傳入的值value 等。

職責(zé):存儲(chǔ)實(shí)際的關(guān)聯(lián)數(shù)據(jù)以及定義數(shù)據(jù)的內(nèi)存管理語(yǔ)義。

工作流程

設(shè)置關(guān)聯(lián)對(duì)象:

調(diào)用 objc_setAssociatedObject。AssociationsManager 查找或創(chuàng)建與目標(biāo)對(duì)象相關(guān)的 ObjectAssociationMap。在 ObjectAssociationMap 中查找或創(chuàng)建對(duì)應(yīng)的 ObjcAssociation。將關(guān)聯(lián)值和存儲(chǔ)策略設(shè)置到 ObjcAssociation 中。 獲取關(guān)聯(lián)對(duì)象:

調(diào)用 objc_getAssociatedObject。AssociationsManager 查找與目標(biāo)對(duì)象相關(guān)的 ObjectAssociationMap。在 ObjectAssociationMap 中查找對(duì)應(yīng)的 ObjcAssociation。返回 ObjcAssociation 中存儲(chǔ)的關(guān)聯(lián)值。 移除關(guān)聯(lián)對(duì)象:

調(diào)用 objc_removeAssociatedObjects 或 objc_setAssociatedObject 設(shè)置為 nil。AssociationsManager 查找與目標(biāo)對(duì)象相關(guān)的 ObjectAssociationMap。從 ObjectAssociationMap 中移除對(duì)應(yīng)的 ObjcAssociation。如果 ObjectAssociationMap 為空,可能會(huì)移除整個(gè)映射以釋放資源。

objc_AssociationPolicy的值并沒(méi)有weak,這點(diǎn)我們?cè)谑褂玫臅r(shí)候需要注意

柚子快報(bào)激活碼778899分享:iOS——分類、擴(kuò)展和關(guān)聯(lián)對(duì)象

http://yzkb.51969.com/

精彩文章

評(píng)論可見(jiàn),查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。

轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://m.gantiao.com.cn/post/19157881.html

發(fā)布評(píng)論

您暫未設(shè)置收款碼

請(qǐng)?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問(wèn)

文章目錄