Associative機制的學習總結

2021-07-02 02:14:21 字數 4025 閱讀 1272

出處:

objective-c

有兩個擴充套件機制:category和associative。我們可以通過category來擴充套件方法,但是它有個很大的侷限性,不能擴充套件屬性。於是,就有了專門用來擴充套件屬性的機制:associative。

在ios開發過程中,category比較常見,而associative就用的比較少。associative的主要原理,就是把兩個物件相互關聯起來,使得其中的乙個物件作為另外乙個物件的一部分。

使用associative,我們可以不用修改類的定義而為其物件增加儲存空間。這在我們無法訪問到類的原始碼的時候或者是考慮到二進位制相容性的時候是非常有用。

associative

是基於關鍵字的。因此,我們可以為任何物件增加任意多的associative,每個都使用不同的關鍵字即可。associative是可以保證被關聯的物件在關聯物件的整個生命週期都是可用的。

associative

機制提供了三個方法:

objc_export

void

objc_setassociatedobject(

idobject,

const

void

*key,

idvalue,

objc_associationpolicy

policy)

objc_export

idobjc_getassociatedobject(

idobject,

const

void

*key)

objc_export

void

objc_removeassociatedobjects(

idobject)

建立associative使用的是:objc_setassociatedobject。它把乙個物件與另外乙個物件進行關聯。該函式需要四個引數:源物件,關鍵字,關聯的物件、關聯策略。

關鍵字是乙個void型別的指標。每乙個關聯的關鍵字必須是唯一的。通常都是會採用靜態變數來作為關鍵字。

關聯策略表明了相關的物件是通過賦值,保留引用還是複製的方式進行關聯的;還有這種關聯是原子的還是非原子的。這裡的關聯策略和宣告屬性時的很類似。這種關聯策略是通過使用預先定義好的常量來表示的。

比如,我們想對乙個uiview,新增乙個nsstring型別的tag。可以這麼做:

- (void)settagstring:(nsstring *)value

獲取相關聯的是函式objc_getassociatedobject。

繼續上面的例子,從乙個uiview的例項中,獲取乙個nsstring型別的tag

- (nsstring *)tagstring 

return nil;

}

斷開associative是使用objc_setassociatedobject函式,傳入nil值即可。

objc_setassociatedobject(self, key_tagstring, nil, objc_association_retain_nonatomic);

使用函式

objc_removeassociatedobjects

可以斷開所有

associative

。通常情況下不建議這麼做,因為他會斷開所有關聯。

上面的例子提到,在uiview中新增nsstring型別的標記,就是乙個非常實用的例子。全部的**如下:

@inte***ce uiview(bdtag)

@property (nonatomic, retain) nsstring *tagstring;

- (uiview *)viewwithtagstring:(nsstring *)value;

@end

#import "uiview+bdtag.h"

#undef key_tagstring

#define key_tagstring "uiview.tagstring"

@implementation uiview(bdtag)

@dynamic tagstring;

- (nsstring *)tagstring

return nil;}

- (void)settagstring:(nsstring *)value

- (uiview *)viewwithtagstring:(nsstring *)value

for (uiview *subview in self.subviews)

}return nil;}

@end

蘋果雖然有提供

nsinteger

型別的tag

屬性,用於標記相應的

ui。但是在處理比較複雜的邏輯的時候,往往

nsinteger

型別的標記不能滿足需求。為其新增了

nsstring

型別的標記後。就能使用字串,快速的標記

ui,並且使用

viewwithtagstring

方法,快速找到你所需要的ui。

這是乙個方便,強大,並且簡單的類。利用associative機制,為任何object,新增你所需要的資訊。比如使用者登入,向服務端傳送使用者名稱/密碼時,可以將這些資訊繫結在請求的項之中。等請求完成後,再取出你所需要的資訊,進行邏輯處理。而不需要另外設定成員,儲存這些資料。

具體的實現如下:

@inte***ce nsobject (bdassociation)

- (id)associatedobjectforkey:(nsstring*)key;

- (void)setassociatedobject:(id)object forkey:(nsstring*)key;

@end

#import "nsobject+bdassociation.h"

@implementation nsobject (bdassociation)

static char associatedobjectskey;

- (id)associatedobjectforkey:(nsstring*)key

- (void)setassociatedobject:(id)object forkey:(nsstring*)key

[dict setobject:object forkey:key];}

@end

記得在我剛開始學ios開發的時候,經常出現記憶體洩露的問題,於是就在各個view controller的dealloc中打log。這種方法雖然有效,但比較挫,不好管理。

這裡貼出一種漂亮的解決方案,利用associative機制。讓object在**時,自動輸出**資訊。

@inte***ce nsobject (bdlogdealloc)

- (void)logondealloc;

@end

#import "nsobject+bdlogdealloc.h"

static char __logdeallocassociatedkey__;

@inte***ce logdealloc : nsobject

@property (nonatomic, copy) nsstring* message;

@end

@implementation nsobject (logdealloc)

- (void)logondealloc }

@end

@implementation logdealloc

- (void)dealloc

@end

以上便是幾種associative機制的使用例子。這只是強大的associative功能中,小小的幾個縮影。有了associative,就能用簡單的幾行**,解決曾經困擾我們許久的問題。

Associative機制使用場景

objective c 有兩個擴充套件機制 category和associative。我們可以通過category來擴充套件方法,但是它有個很大的侷限性,不能擴充套件屬性。於是,就有了專門用來擴充套件屬性的機制 associative。在ios開發過程中,category比較常見,而associat...

1 請教fork執行機制 UNIX環境程式設計學習

先看 書中分析 呼叫f o r k建立乙個新程序。新程序是呼叫程序的複製品,故稱呼叫程序為父程序,新創 建的程序為子程序。f o r k對父程序返回新子程序的非負程序i d,對子程序則返回0。因為f o r k創 建一新程序,所以說它被呼叫一次 由父程序 但返回兩次 在父程序中和在子程序中 但是測試...

從零開始學MFC 3 訊息對映機制

相對於qt的訊號與槽機制,mfc提供了一套訊息對映機制來處理各種訊息。步驟 1 宣告巨集,寫到.h中 declare message map 2 分界巨集 寫到.cpp中 begin message map myframe,cframewnd 訊息巨集 end message map 3 找訊息巨集...