關聯(lián)
關聯(lián)是指把兩個對象相互關聯(lián)起來窿冯,使得其中的一個對象作為另外一個對象的一部分。
關聯(lián)特性只有在Mac OS X V10.6以及以后的版本上才是可用的确徙。
使用關聯(lián)醒串,我們可以不用修改類的定義而為其對象增加存儲空間。這在我們無法訪問到類的源碼的時候或者是考慮到二進制兼容性的時候是非常有用鄙皇。
關聯(lián)是基于關鍵字的芜赌,因此,我們可以為任何對象增加任意多的關聯(lián)伴逸,每個都使用不同的關鍵字即可缠沈。關聯(lián)是可以保證被關聯(lián)的對象在關聯(lián)對象的整個生命周期都是可用的(在垃圾自動回收環(huá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ù)組上。
列表7-1 把一個字符串關聯(lián)到一個數(shù)組
[cpp]view plaincopy
staticcharoverviewKey;
NSArray?*?array?=[[NSArray?alloc]?initWidthObjects:@"One",?@"Two",?@"Three",?nil];
//為了演示的目的,這里使用initWithFormat:來確保字符串可以被銷毀
NSString?*?overview?=?[[NSString?alloc]?initWithFormat:@"@",@"First?three?numbers"];
objc_setAssociatedObject(array,?&overviewKey,?overview,?OBJC_ASSOCIATION_RETAIN);
[overview?release];
//(1)?overview仍然是可用的
[array?release];
//(2)overview?不可用
在(1)處遇西,字符串overview仍然是可用的馅精,這是因為OBJC_ASSOCIATION_RETAIN策略指明了數(shù)組要保有相關的對象。當數(shù)組array被銷毀的時候粱檀,也就是在(2)處overview也就會被釋放洲敢,因此而被銷毀。如果此時還想使用overview茄蚯,例如想通過log來輸出overview的值压彭,則會出現(xiàn)運行時異常。
獲取相關聯(lián)的對象時使用Objective-C函數(shù)objc_getAssociatedObject渗常。接著上面列表7-1的代碼壮不,我們可以使用如下代碼來獲取與array相關聯(lián)的字符串:
[cpp]view plaincopy
NSString?*?associatedObject?=?(NSString?*)objc_getAssociatedObject(array,?&oveviewKey);
斷開關聯(lián)是使用objc_setAssociatedObject函數(shù),傳入nil值即可皱碘。
接著列表7-1中的程序询一,我們可以使用如下的代碼來斷開字符串overview和arry之間的關聯(lián):
[cpp]view plaincopy
objc_setAssociatedObject(array,?&overviewKey,?nil,?OBJC_ASSOCIATION_ASSIGN);
其中坑雅,被關聯(lián)的對象為nil朽褪,此時關聯(lián)策略也就無關緊要了。
使用函數(shù)objc_removeAssociatedObjects可以斷開所有關聯(lián)罩缴。通常情況下不建議使用這個函數(shù)踢俄,因為他會斷開所有關聯(lián)缩功。只有在需要把對象恢復到“原始狀態(tài)”的時候才會使用這個函數(shù)。
下面的程序綜合了前面的代碼.
[cpp]view plaincopy
#import?
#import?
intmain(intargc,constchar*?argv[])
{
NSAutoreleasePool?*?pool?=?[[NSAutoreleasePool]?alloc?init];
staticcharoverviewKey;
NSArray?*array?=[[NSArray?alloc]?initWidthObjects:@"One",?@"Two",?@"Three",?nil];
//為了演示的目的都办,這里使用initWithFormat:來確保字符串可以被銷毀
NSString?*?overview?=?[[NSString?alloc]?initWithFormat:@"@",@"First?three?numbers"];
objc_setAssociatedObject(array,?&overviewKey,?overview,?OBJC_ASSOCIATION_RETAIN);
[overview?release];
NSString?*associatedObject?=?(NSString?*)objc_getAssociatedObject(arrray,?&overviewKey);
NSLog(@"associatedObject:%@",?associatedObject);
objc_setAssociatedObject(array,?&overviewKey,?nil,?OBJC_ASSOCIATION_ASSIGN);
[array?release];
[pool?drain];
return0;
}
轉載于:http://blog.csdn.net/onlyou930/article/details/9299169