objc_setAssociatedObject實(shí)現(xiàn)與weak等效的關(guān)聯(lián)類型

設(shè)置關(guān)聯(lián)對象可選的關(guān)聯(lián)類型有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. */
};

分別對應(yīng)屬性的內(nèi)存管理語義的assing、nonatomic,retain、nonatomic,copy、retain、copy,
缺少了weak對應(yīng)的類型,可以用一個(gè)中間對象實(shí)現(xiàn)與weak等效的關(guān)聯(lián)類型:

  • 用OBJC_ASSOCIATION_RETAIN_NONATOMIC的方式關(guān)聯(lián)一個(gè)中間對象,這個(gè)對象相當(dāng)于一個(gè)容器,里面弱引用了我們的目標(biāo)對象
  • 當(dāng)我們需要拿到目標(biāo)對象時(shí),先取出中間對象,因?yàn)橹虚g對象是被強(qiáng)引用的,所以一定存在,再取出其中的被弱引用的目標(biāo)對象,如果目標(biāo)對象已經(jīng)delloc,指針自動(dòng)置空,并不會(huì)造成野指針的崩潰。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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。