美文网首页
objc_setAssociatedObject实现与weak等

objc_setAssociatedObject实现与weak等

作者: cocoa | 来源:发表于2018-01-17 16:45 被阅读25次

    设置关联对象可选的关联类型有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

    相关文章

      网友评论

          本文标题:objc_setAssociatedObject实现与weak等

          本文链接:https://www.haomeiwen.com/subject/ezsuoxtx.html