無論在MRC下還是ARC下均不需要屯阀,被關(guān)聯(lián)的對象在生命周期內(nèi)要比對象本身釋放的晚很多,它們會在被 NSObject -dealloc 調(diào)用的object_dispose()方法中釋放轴术。
關(guān)聯(lián)對象的實現(xiàn)
我們在 iOS 開發(fā)中經(jīng)常需要使用分類(Category)难衰,為已經(jīng)存在的類添加屬性的需求,但是使用 @property 并不能在分類中正確創(chuàng)建實例變量和存取方法逗栽。
不過盖袭,通過 Objective-C 運行時中的關(guān)聯(lián)對象,也就是 Associated Object彼宠,我們可以實現(xiàn)上述需求鳄虱。
#import "DKObject+Category.h"
#import <objc/runtime.h>
@implementation DKObject (Category)
- (void)setName:(NSString *)name {
objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)name {
// 隱式參數(shù)
// _cmd == @selector(name)
return objc_getAssociatedObject(self, _cmd);
}
@end
我們使用了兩個方法 objc_getAssociatedObject
以及 objc_setAssociatedObject
來模擬『屬性』的存取方法,而使用關(guān)聯(lián)對象模擬實例變量兵志。
我們從三個 objc 運行時的方法為入口來對關(guān)聯(lián)對象的實現(xiàn)一探究竟醇蝴,其中兩個方法是上一部分使用到的方法:
NSLog(@"以鍵值對形式添加關(guān)聯(lián)對象")
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
NSLog(@"根據(jù) key 獲取關(guān)聯(lián)對象")
id objc_getAssociatedObject(id object, const void *key);
NSLog(@"移除所有關(guān)聯(lián)對象")
void objc_removeAssociatedObjects(id object);
在這里有必要解釋兩個問題:
- 為什么向方法中傳入 @selector(name)宣肚?
- OBJC_ASSOCIATION_RETAIN_NONATOMIC 是干什么的想罕?
關(guān)于第一個問題,我們需要看一下這兩個方法的原型:
id objc_getAssociatedObject(id object, const void *key);
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
@selector(name) 也就是參數(shù)中的 key霉涨,其實可以使用靜態(tài)指針 static void * 類型的參數(shù)來代替按价,不過在這里,筆者強烈推薦使用 @selector(name) 作為 key 傳入笙瑟。因為這種方法省略了聲明參數(shù)的代碼楼镐,并且能很好地保證 key 的唯一性。
OBJC_ASSOCIATION_RETAIN_NONATOMIC 又是什么呢往枷?
typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
OBJC_ASSOCIATION_ASSIGN = 0, // 指定一個弱引用相關(guān)聯(lián)的對象
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, // 指定相關(guān)對象的強引用框产,非原子性
OBJC_ASSOCIATION_COPY_NONATOMIC = 3, // 指定相關(guān)的對象被復(fù)制凄杯,非原子性
OBJC_ASSOCIATION_RETAIN = 01401, // 指定相關(guān)對象的強引用,原子性
OBJC_ASSOCIATION_COPY = 01403 // 指定相關(guān)的對象被復(fù)制秉宿,原子性
};
從這里的注釋我們能看到很多東西戒突,也就是說不同的 objc_AssociationPolicy 對應(yīng)了不通的屬性修飾符:
objc_AssociationPolicy | modifier |
---|---|
OBJC_ASSOCIATION_ASSIGN | assign |
OBJC_ASSOCIATION_RETAIN_NONATOMIC | nonatomic, strong |
OBJC_ASSOCIATION_COPY_NONATOMIC | nonatomic, copy |
OBJC_ASSOCIATION_RETAIN | atomic, strong |
OBJC_ASSOCIATION_COPY | atomic, copy |