設置關聯對象可選的關聯類型有5種:
/* Associative References */
/**
* Policies related to associative references.
* These are options to objc_setAssociatedObject()
*/
typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
OBJC_ASSOCIATION_ASSIGN = 0, /**< Specifies a weak reference to the associated object. */
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object.
* The association is not made atomically. */
OBJC_ASSOCIATION_COPY_NONATOMIC = 3, /**< Specifies that the associated object is copied.
* The association is not made atomically. */
OBJC_ASSOCIATION_RETAIN = 01401, /**< Specifies a strong reference to the associated object.
* The association is made atomically. */
OBJC_ASSOCIATION_COPY = 01403 /**< Specifies that the associated object is copied.
* The association is made atomically. */
};
分別對應屬性的內存管理語義的assing、nonatomic,retain、nonatomic,copy、retain、copy,
缺少了weak對應的類型,可以用一個中間對象實現與weak等效的關聯類型:
- 用OBJC_ASSOCIATION_RETAIN_NONATOMIC的方式關聯一個中間對象,這個對象相當于一個容器,里面弱引用了我們的目標對象
- 當我們需要拿到目標對象時,先取出中間對象,因為中間對象是被強引用的,所以一定存在,再取出其中的被弱引用的目標對象,如果目標對象已經delloc,指針自動置空,并不會造成野指針的崩潰。OBJC_ASSOCIATION_ASSIGN是做不到的。
- (id)delegate {
LLSWeakObjectContainer *container = objc_getAssociatedObject(self, xxx);
return container.weakObject;
}
- (void)setDelegate:(id)delegate {
objc_setAssociatedObject(self, xxx, [[LLSWeakObjectContainer alloc] initWithWeakObject:delegate], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@interface LLSWeakObjectContainer : NSObject
@property (nonatomic, readonly, weak) id weakObject;
- (instancetype)initWithWeakObject:(id)object;
@end
@implementation LLSWeakObjectContainer
- (instancetype)initWithWeakObject:(id)object
{
self = [super init];
if (self) {
_weakObject = object;
}
return self;
}
@end
參考DZNEmptyDataSet:DZNWeakObjectContainer