Want to perform action when __weak ivar is niled
Asked Answered
A

3

7

I have a @class Foo which contains a __weak id bar ivar. Several actions from methods in different classes can cause the object to disappear and thus get bar niled.

I want to perform an action when the ivar is automatically niled by ARC.

If possible, I would want to avoid turning bar into a property or using Key-Value Observing.

Is this even possible? If not, can KVO be used against non-property ivars?

Abuttals answered 19/2, 2013 at 12:21 Comment(6)
The convention says you should name it __weak id bar. Do you know of which class is this variable? You could handle this in the dealloc method.Pallet
Ramy: Yeah, my fault, I fixed it in the question (its actual name started with lower case). Regarding dealloc, if possible I would also like to avoid using bar's dealloc method. I'd like to trigger this action within @class Foo.Abuttals
I think you want too much.Eyecatching
Hot Licks: If it cannot be done my way, it will settle with turning bar into a property and using KVO. It doesn't hurt to ask, just in case. ;-)Abuttals
KVO works on ivars, too. The more precise rules are in the docs.Cablet
@Monolo: KVO doesn't work on ivars.Abuttals
A
2

KVO cannot be successfully used on non-property IVARs.

You cannot detect from the runtime when Objective-C's ARC nils an IVAR.

Abuttals answered 16/9, 2013 at 12:3 Comment(0)
H
4

I was led here by a duplicate question, here is what I answered:

You can't do that with KVO, but you can still get a notification and emulate this by associating an object with your iVar using objc_setAssociatedObject(), it will be deallocated when the weak variable dies.

@interface WeakObjectDeathNotifier : NSObject
@end
@implementation WeakObjectDeathNotifier
- (void)dealloc
{
    // the code that shall fire when the property will be set to nil
}
@end

You can build on top of that very elaborate notifiers, using NSNotificationCenter or just custom blocks, depending on how heavily you rely on that for a specific ivar case or for lots of them.

The good thing about this solution is that it works with any __weak ivar, even if you don't control the type the __weak ivar has.

Hypotonic answered 6/12, 2013 at 14:13 Comment(0)
A
2

KVO cannot be successfully used on non-property IVARs.

You cannot detect from the runtime when Objective-C's ARC nils an IVAR.

Abuttals answered 16/9, 2013 at 12:3 Comment(0)
P
0

I suggest to override dealloc. If you know the type of the object that will be allocated, and it's a custom class (otherwise subclass it), you can perform the action when the object is deallocated, which is exactly what happens when ARC sets the retain count to zero and sets the weak variable to nil.

Pallet answered 19/2, 2013 at 12:58 Comment(7)
I'll accept this one unless a method without using KVO pops out. Cheers!Abuttals
Hmm, I tried this and the -(void)observeValueForKeyPath:... method doesn't trigger, even though bar is being set to nil by ARC (I'm monitoring it, and I can see it being set to nil). The documentation seems to state that it only works for properties. Are you sure that it works for ivars?Abuttals
Ok, upon further testing, -(void)observeValueForKeyPath:... is triggered if I set the ivar doing [self setValue:object forKey:@"bar"], but it doesn't trigger if I set it doing bar = object. In any case, it also does not trigger when ARC sets it to nil, which is what I'm looking for.Abuttals
Additional note: even after making bar a property, the KVO notification is not triggered when ARC nils it.Abuttals
I was not the one who downvoted, but if I had to guess the reasons: 1) it doesn't tell me anything that I don't know; 2) it contained missfactual information before your edit; 3) your edit allows you to realize that your answer contains missfactual information, but this is not evident on a quick read because you added that text as a disclaimer as opposed to fixing the question. If you care about downvotes my advice is that you either rewrite the question completely or delete it altogether.Abuttals
overriding dealloc of what exactly? If the ivar is an NSString are you really suggesting to override -[NSString dealloc] ? and what do you do when the property you want to do KVO on is on a class where you don't control the type of the object that is set?Hypotonic
The variable is __weak id bar. He wants to know when the pointer is nil'd. I say he overrides dealloc of whatever class is bar.Pallet

© 2022 - 2024 — McMap. All rights reserved.