第十條:在既有類中使用關(guān)聯(lián)對(duì)象存放自定義數(shù)據(jù)
有時(shí)需要在對(duì)象中存放相關(guān)信息。
這時(shí)我們通常會(huì)從對(duì)象所屬的類中繼承一個(gè)子類,然后改用這個(gè)子類對(duì)象。
并非所有的情況下都能這么做,有時(shí)候類的實(shí)例可能是由某種機(jī)制所創(chuàng)建的。
而開發(fā)者無(wú)法令這種機(jī)制創(chuàng)建出自己所寫的子類實(shí)例。
Objective-C中有一項(xiàng)強(qiáng)大的特性可以解決此問題,這就是“關(guān)聯(lián)對(duì)象”(Associated Object)。
可以給某對(duì)象關(guān)聯(lián)許多其他對(duì)象,這些對(duì)象通過“鍵”來(lái)區(qū)分。
存儲(chǔ)對(duì)象值的適合,可以指明“存儲(chǔ)策略”(Strong policy),用以維護(hù)相應(yīng)的“內(nèi)存管理語(yǔ)義”。
存儲(chǔ)策略由名為objc_AssociationPolicy的枚舉所定義。
等效的@property屬性:假如關(guān)聯(lián)對(duì)象成為了屬性,那么它就會(huì)具備對(duì)應(yīng)的語(yǔ)義。
【對(duì)象關(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
下列方法可以管理關(guān)聯(lián)對(duì)象:
此方法以給定的鍵和策略為某對(duì)象設(shè)置關(guān)聯(lián)對(duì)象值
void objc_setAssociatedObject (id object, void *key, id value, objc_AssociationPolicy policy)
此方法根據(jù)給定的鍵從某對(duì)象中獲取相應(yīng)的關(guān)聯(lián)對(duì)象值
id objc_getAssociatedObject (id object, void *key)
此方法移除指定對(duì)象的所有關(guān)聯(lián)對(duì)象值
void objc_removeAssociatedObjects (id object)
這種方法很有用,但是只應(yīng)該在沒有其他的辦法達(dá)成你想做的事情的時(shí)候用到它。
若是濫用,則很快就會(huì)令代碼失控,使其難于調(diào)試。
使用了“塊”(block)可能會(huì)捕獲(capture)某些變量,這也許會(huì)造成“循環(huán)引用”(reatain cycle)。
使用這種方法(approach)時(shí)要特別小心,不能僅僅因?yàn)槟程幙梢杂迷摲椒ň鸵欢ㄒ盟?/p>
【要點(diǎn)】
1.可以通過“關(guān)聯(lián)對(duì)象”機(jī)制來(lái)把兩個(gè)對(duì)象連起來(lái)
2.定義關(guān)聯(lián)對(duì)象時(shí)可指定內(nèi)存管理語(yǔ)義,用以模仿定義屬性時(shí)所采用的“擁有關(guān)系”與“非擁有關(guān)系”
3.只有在其他做法不可行時(shí),才應(yīng)選用關(guān)聯(lián)對(duì)象,因?yàn)檫@種做法通常會(huì)引入難于查找的bug
【Things to Remember】
1.Associated objects provide a means of linking two objects toghter
2.The memory-management semantics of associated objects can be defined to mimic owning or nonowning relationships.
3.Associated objects should be used only when another approach is not possible,since they can easily introduce hard-to-find bugs.