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
inself
.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
#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比較常見,而assoc...
Cookie使用機制
我們就需要用一些技術來幫助伺服器去識別使用者 cookie 在客戶端儲存使用者標識資訊。識別使用者,持久化最好的方式。cookie原理 1 首次訪問web站點時,web伺服器對使用者一無所知。web伺服器希望這個使用者再次回來還能認識它。所以想給這個使用者乙個標識。標籤。set cookie use...
android binder機制簡單使用
需求 最近公司需要在native層寫乙個c 服務,用來與上層通訊,由於自己並不是很精通c 所以決定從簡單的入手,先嘗試寫乙個binder服務。具體實現 實現乙個binder通訊例項,需要經過以下步驟 1 獲得servicemanager的物件引用 2 向servicemanager註冊新的servi...