I know that OBJC_ASSOCIATION_ASSIGN exists, but does it zero the reference if the target object is dealloced? Or is it like the old days where that reference needs to get nil-ed or we risk a bad access later on?
As ultramiraculous demonstrated, OBJC_ASSOCIATION_ASSIGN
does not do zeroing weak reference and you risk to access a deallocated object. But it’s quite easy to implement yourself. You just need a simple class to wrap an object with a weak reference:
@interface WeakObjectContainer : NSObject @property (nonatomic, readonly, weak) id object; @end @implementation WeakObjectContainer - (instancetype) initWithObject:(id)object { if (!(self = [super init])) return nil; _object = object; return self; } @end
Then you must associate the WeakObjectContainer
as OBJC_ASSOCIATION_RETAIN(_NONATOMIC):
objc_setAssociatedObject(self, &MyKey, [[WeakObjectContainer alloc] initWithObject:object], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
and use the object
property to access it in order to get a zeroing weak reference:
id object = [objc_getAssociatedObject(self, &MyKey) object];
One more option similar to WeakObjectContainer
:
- (id)weakObject { id (^block)(void) = objc_getAssociatedObject(self, @selector(weakObject)); return (block ? block() : nil); } - (void)setWeakObject:(id)object { id __weak weakObject = object; id (^block)(void) = ^{ return weakObject; }; objc_setAssociatedObject(self, @selector(weakObject), block, OBJC_ASSOCIATION_COPY); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With