第10條:在既有類中使用關(guān)聯(lián)對(duì)象存放自定義數(shù)據(jù)
1. 關(guān)聯(lián)對(duì)象
可以給某對(duì)象關(guān)聯(lián)許多其他對(duì)象,這些對(duì)象通過(guò)“鍵”來(lái)區(qū)分,這就是關(guān)聯(lián)對(duì)象。存儲(chǔ)對(duì)象值的時(shí)候,可以指明“存儲(chǔ)策略”(storage policy),用以維護(hù)相應(yīng)的“內(nèi)存管理語(yǔ)義”
*** 存儲(chǔ)策略 ***
存儲(chǔ)策略由名為objc_AssociationPolicy的枚舉所定義的。
下表為:
該枚舉的取值和與之對(duì)應(yīng)的@property屬性。
表 對(duì)象關(guān)聯(lián)類型
關(guān)聯(lián)類型 | 等效的@property屬性 |
---|---|
OBJC_ASSOCIATION_ASSIGN | assign |
OBJC_ASSOCIATION_RETAIN_NONATOMIC | nonatomic,retain |
OBJC_ASSOCIATION_COPY_NONATOMIC | nonatomic, copy |
OBJC_ASSOCIATION_RETAIN | retain |
OBJC_ASSOCIATION_COPY | copy |
下列方法可以管理管理對(duì)象:
- void objc_setAssociatedObject(id object, void*key, id value, objc_AssociationPolicy)
此方法以給定的鍵和策略為某對(duì)象設(shè)置關(guān)聯(lián)對(duì)象值。 - id objc_getAssociatedObject(id object, void*key)
此方法根據(jù)給定的鍵從某對(duì)象中獲取相應(yīng)的關(guān)聯(lián)對(duì)象值。 - void objc_removeAssociatedObjects(id object)
此方法移除指定對(duì)象的全部關(guān)聯(lián)對(duì)象。
由于設(shè)置關(guān)聯(lián)對(duì)象時(shí)所用的鍵是個(gè)“不透明的指針”(opaque pointer),所以在設(shè)置關(guān)聯(lián)對(duì)象值時(shí),若想令兩個(gè)鍵匹配到同一個(gè)值,則兩者必須是完全相同的指針才行。鑒于此,在設(shè)置關(guān)聯(lián)對(duì)象值時(shí),通常使用靜態(tài)全局變量做鍵。
2. 關(guān)聯(lián)對(duì)象用法舉例
例子:在一個(gè)類里創(chuàng)建一個(gè)警告視圖后,設(shè)定一個(gè)與之關(guān)聯(lián)的“塊”并將它們放在同一作用域里,等到執(zhí)行delegate方法時(shí)再將其讀出來(lái)。這種方式創(chuàng)建的UIAlertView與處理操作結(jié)果的代碼都放在一起,更易讀懂。但是,由于塊可能要捕獲某些變量,也會(huì)造成“保留環(huán)”。
總結(jié):這種做法只應(yīng)該在其他辦法行不通時(shí)才去考慮用它
作者推薦:若是多次用到alert視圖,有個(gè)更好的辦法,那就是從中繼承子類,把塊保存為子類中的屬性。
要點(diǎn)
- 可以通過(guò)“關(guān)聯(lián)對(duì)象”機(jī)制來(lái)把兩個(gè)對(duì)象連起來(lái)。
- 定義關(guān)聯(lián)對(duì)象時(shí)可指定內(nèi)存管理語(yǔ)義,用以模仿定義屬性時(shí)所采用的“擁有關(guān)系”與“非擁有關(guān)系”。
- 只有在其他做法不可行時(shí)才應(yīng)選用關(guān)聯(lián)對(duì)象,因?yàn)檫@種做法通常會(huì)引起難于查找的bug。