美文网首页
如何在关联对象上使用 weak

如何在关联对象上使用 weak

作者: yww | 来源:发表于2017-07-31 15:16 被阅读118次

要在 category 中定义属性, 唯一的办法就是使用关联对象. 但是关联对象的存储方式只有 assign, retain, copy 三种, 并没有 weak. 想要使用 weak 属性就要自己想办法了.

我们自定义类如下

@interface MyObject : NSObject
@end

@implementation MyObject
@end

测试代码如下, 在一个 viewcontroller 的 viewDidLoad 中, 我们定义一个 MyObject 对象, 并未其中的 weakObj 赋值.

- (void)viewDidLoad {
    [super viewDidLoad
![](https://img.haomeiwen.com/i943998/014e43df98242088.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
];
    self.myObj = [MyObject new];
    self.myObj.weakvalue = [NSObject new];
}

在viewDidDisappear 中去获取值

-(void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    NSLog(@"weak value is: %@", self.myObj.weakvalue);
}

直接使用 assign

代码如下

void *weakValueKey = NULL;
-(void)setWeakvalue:(NSObject *)weakvalue {
    objc_setAssociatedObject(self, weakValueKey, weakvalue, OBJC_ASSOCIATION_ASSIGN);
}
-(NSObject *)weakvalue {
    return objc_getAssociatedObject(self, weakValueKey);
}

不用怀疑, 不会自动值为 nil , 如果在对象释放之后访问, 将会直接崩溃.


崩溃了

解决方案

最简单的解决方案就是使用 block 包起来. 先来看代码

-(void)setWeakvalue:(NSObject *)weakvalue {
    __weak typeof(weakvalue) weakObj = weakvalue;
    typeof(weakvalue) (^block)() = ^(){
        return weakObj;
    };
    objc_setAssociatedObject(self, weakValueKey, block, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
-(NSObject *)weakvalue {
    id (^block)() = objc_getAssociatedObject(self, weakValueKey);
    return block();
}

运行结果


image.png

原理解析:

首先我们在 setter 方法里面使用了一个weak 的局部变量 weakObj 来存储值. 并在 block 中将其捕获并返回.
由于 weakObj 是弱引用, 所以不会修改对象的引用计数. 当对象释放时, 由于 weakObj的 weak属性, 它也会在释放后指向�nil. 所以�挡在 getter 中返回的时候, 自然也是返回 nil.

demo 在这里, https://github.com/ywwzwb/AssociateWeakDemo

相关文章

  • 如何在关联对象上使用 weak

    要在 category 中定义属性, 唯一的办法就是使用关联对象. 但是关联对象的存储方式只有 assign, r...

  • Catagory 模拟添加 Weak 属性

    1、关联对象模拟weak的实现,自动置空 NSObject+weak.h NSObject+weak.m 测试使用...

  • 分类添加weak属性

    1、增加中间变量 NSObject+weak2.h NSObject+weak2.m 测试使用 2、关联策略使用A...

  • iOS原理篇(四):关联对象

    关联对象的使用场合 关联对象的基本使用 关联对象的底层原理 一、关联对象的使用场合默认情况下,因为分类底层结构的限...

  • @property weak与assign有什么不同

    @property weak与assign的区别 weak 使用于NSObject 对象类型 assign 用于基...

  • 在ARC中为啥要用weak修饰弱引用

    weak和assign的区别 weak只能用来修饰对象,使用weak修饰的对象的默认值是nil,不能用来修饰基本数...

  • iOS相关知识(十)-- weak

    weak的基本使用 weak是弱引用,当一个对象被weak修饰的时候,这个对象的引用计数并不会增加,且这个对象被释...

  • iOS __weak的底层实现

    1.为什么要使用weak关键字修饰对象 因为使用weak修饰的对象在对象释放的时候,引用它的指针会自动被置为nil...

  • weak的底层的实现

    1.为什么要使用weak关键字修饰对象 因为使用weak修饰的对象在对象释放的时候,引用它的指针会自动被置为nil...

  • ThreadLocal

    问题一:为什么ThreadLocal中的map对象为什么key是weak类型的? 弱引用概念:弱引用关联的对象只能...

网友评论

      本文标题:如何在关联对象上使用 weak

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