runtime 二 給物件 分類新增例項變數

2021-09-11 13:00:44 字數 3055 閱讀 2682

在開發中有時候想給物件例項新增個變數來儲存資料,但又無法直接宣告,比如說既有類的分類。這個時候我們就可以通過關聯物件在執行時給物件關聯乙個物件來儲存資料。(注意:並不是真實的新增了乙個例項變數)

關聯物件可以給某個物件關聯其他物件並用key來區分其他物件。需要注意的是,儲存物件的時候要指明儲存策略,用來維護物件的記憶體管理語義。儲存策略是objc_associationpolicy列舉定義,以下是儲存策略對應的@property屬性:

儲存策略型別

對應的@property屬性

objc_association_assign

weak

objc_association_retain_nonatomic

strong, nonatomic

objc_association_copy_nonatomic

copy, nonatomic

objc_association_retain

strong

objc_association_copy

copy

用下面的方法可以管理關聯物件:

// 這個方法可以根據指定策略給物件關聯物件值

void objc_setassociatedobject(id object, const

void *key, id value, objc_associationpolicy policy)

// 這個方法可以獲取物件關聯物件值

id objc_getassociatedobject(id object, const

void *key)

// 這個方法可以刪除指定物件的全部關聯物件值

void objc_removeassociatedobjects(id object)

複製**

對於關聯物件這個oc特性,我們可以把物件想象成乙個 nsdictionary,關聯物件需要乙個key( 型別是 opaque pointer,無型別的指標 ) 來區分,我們可以把要新增的變數名作為key,把變數的值作為關聯的物件來儲存到 」物件「 這個 nsdictionary 中。 所以,關聯物件的

void objc_setassociatedobject(id object, const

void *key, id value, objc_associationpolicy policy)

複製**

方法類似於字典的[dict setobject: forkey:]方法。

在儲存和獲取關聯物件時需要用乙個相等的key,因為是給 class 的例項物件關聯物件,所以一般用靜態變數來做key

說的再多,不如上段**!

比如說,我們給nsstring例項加上個nsdate型別的date變數。什麼?給字串加個日期變數是要幹嫋?我要給字串過個生日不行嗎! 別鬧,舉個栗子嘛!(捂臉逃跑~~~)

首先,我們先給nsstring新建個名為rt的 category。 在標頭檔案中有個 nsdate 型別的 date 屬性:

//  nsstring+rt.h

// runtime

#import

//@inte***ce

nsstring (rt)

//@property (nonatomic, strong) nsdate *date;

//@end

複製**

在分類中的屬性只會生成getset方法,並不會生成變數。 所以我們需要重寫getset方法,關聯物件以變相實現新增變數,在現實檔案中:

//  nsstring+rt.m

// runtime

#import

#import "nsstring+rt.h"

//@implementation

nsstring (rt)

//static

void *runtime_date_key = "date";

- (nsdate *)date

//- (void)setdate:(nsdate *)date

@end

複製**

需要注意的是,關聯物件用到的key是個無型別的指標,一般來說是靜態來修飾。 另外,給物件關聯的只能是物件,如果是intfloat等型別需要nsnumber進行包裝。 因為date是強引用和非原子屬性,所以關聯策略用objc_association_retain_nonatomic

然後執行**:

nsstring *string = @"runtimeteststring";

string.date = [nsdate date];

nslog(@"string.date = %@",string.date);

複製**

輸出結果:

2016

-04-12

21:27:31.099 runtime[2837:103727] string.date = 2016

-04-12

13:27:31 +0000

複製**

注意:

我的部落格:iosgg.cn/

iOS分類中通過runtime新增動態屬性

1.先建立乙個類 property assign,nonatomic nsinteger age void run end import person.h implementation person void run end2.定義分類 import person.h inte ce person ...

iOS分類中通過runtime新增動態屬性

這個的話並不是說 可以 在程式執行的時候 來幾個 未知的東西 就新增什麼 1 2 3 4 5的屬性。而是可以在系統原有類的基礎上 給那個類 集合實際的工程來新增你方便實用的東西。比如 乙個 label 有 乙個 backgroundcolor屬性,我要給它新增乙個 其他的 比如 文字 第乙個字的co...

iOS 用runtime為分類新增成員變數或屬性

關於ios分類 很多說法是只能新增方法,而不能新增成員變數或屬性。有些人可能知道,這種說法是不嚴謹的,並不是絕對不能新增變數。解釋如下 我們知道在乙個類中用 property宣告屬性,編譯器會自動幫我們生成 成員變數和setter getter,但分類的指標結構體中,根本沒有屬性列表。所以在分類中用...