iOS關聯(lián),objc_getAssociatedObject, objc_setAssociatedObject

關聯(lián)

category與associative作為objective-c的擴展機制的兩個特性,category即類型,可以通過它來擴展方法;associative,可以通過它來擴展屬性;在iOS開發(fā)中,可能category比較常見,相對的associative,就用的比較少,要用它必須使用的頭文件,然后就可以自由使用objc_getAssociatedObject以及objc_setAssociatedObject

關聯(lián)是指把兩個對象相互關聯(lián)起來,使得其中的一個對象作為另外一個對象的一部分。

在類的定義之外為類增加額外的存儲空間

使用關聯(lián),我們可以不用修改類的定義而為其對象增加存儲空間。這在我們無法訪問到類的源碼的時候或者是考慮到二進制兼容性的時候是非常有用。

關聯(lián)是基于關鍵字的,因此,我們可以為任何對象增加任意多的關聯(lián),每個都使用不同的關鍵字即可。關聯(lián)是可以保證被關聯(lián)的對象在關聯(lián)對象的整個生命周期都是可用的(在垃圾自動回收環(huán)境下也不會導致資源不可回收)。

創(chuàng)建關聯(lián)

創(chuàng)建關聯(lián)要使用到Objective-C的運行時函數(shù):objc_setAssociatedObject來把一個對象與另外一個對象進行關聯(lián)。該函數(shù)需要四個參數(shù):源對象,關鍵字,關聯(lián)的對象和一個關聯(lián)策略。當然,此處的關鍵字和關聯(lián)策略是需要進一步討論的。

■ ?關鍵字是一個void類型的指針。每一個關聯(lián)的關鍵字必須是唯一的。通常都是會采用靜態(tài)變量來作為關鍵字。

■ ?關聯(lián)策略表明了相關的對象是通過賦值,保留引用還是復制的方式進行關聯(lián)的;還有這種關聯(lián)是原子的還是非原子的。這里的關聯(lián)策略和聲明屬性時的很類似。這種關聯(lián)策略是通過使用預先定義好的常量來表示的。

下面的代碼展示了如何把一個字符串關聯(lián)到一個數(shù)組上。

[objc]view plaincopy

staticcharoverviewKey;

NSArray*?array?=[[NSArrayalloc]initWidthObjects:@"One",@"Two",@"Three",nilnil];

//為了演示的目的,這里使用initWithFormat:來確保字符串可以被銷毀

NSString*?overview?=?[[NSStringalloc]initWithFormat:@"@",@"First?three?numbers"];

objc_setAssociatedObject(array,?&overviewKey,?overview,?OBJC_ASSOCIATION_RETAIN);

[overviewrelease];

//(1)?overview仍然是可用的

[arrayrelease];

//(2)overview?不可用

在(1)處,字符串overview仍然是可用的,這是因為OBJC_ASSOCIATION_RETAIN策略指明了數(shù)組要保有相關的對象。當數(shù)組array被銷毀的時候,也就是在(2)處overview也就會被釋放,因此而被銷毀。如果此時還想使用overview,例如想通過log來輸出overview的值,則會出現(xiàn)運行時異常。

獲取相關聯(lián)的對象

獲取相關聯(lián)的對象時使用Objective-C函數(shù)objc_getAssociatedObject。接著上面列表7-1的代碼,我們可以使用如下代碼來獲取與array相關聯(lián)的字符串:

[objc]view plaincopy

NSString*?associatedObject?=?(NSString*)objc_getAssociatedObject(array,?&oveviewKey);

斷開關聯(lián)

斷開關聯(lián)是使用objc_setAssociatedObject函數(shù),傳入nil值即可。

接著列表7-1中的程序,我們可以使用如下的代碼來斷開字符串overview和arry之間的關聯(lián):

[objc]view plaincopy

objc_setAssociatedObject(array,?&overviewKey,nil,?OBJC_ASSOCIATION_ASSIGN);

其中,被關聯(lián)的對象為nil,此時關聯(lián)策略也就無關緊要了。

使用函數(shù)objc_removeAssociatedObjects可以斷開所有關聯(lián)。這個函數(shù)的主要目的是很容易的讓對象恢復成它“原始狀態(tài)”,你不應該使用它來移除關聯(lián)的對象,因為它也會移除掉包括其他地方加入的全部的關聯(lián)對象。所以一般你只需要通過調用objc_setAssociatedObject并傳入nil值來清除關聯(lián)值。

完整實例程序

下面的程序綜合了前面的代碼.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容