Question

I'm currently working on fixing some iOS 7 display issues on a legacy app which was not built with ARC, and have run into some inconsistent behaviour with the dealloc method between iOS versions 6 & 7. I can't find any other mention of these changes in any documentation or community discussions, so I wonder if anyone here could shed some light on what's happening here?

My previous code, (which works in iOS6, looks like this):

@interface MyViewController()
@property (retain) AdHandler *adHandler;
@end

@implementation MyViewController

@synthesize adHandler = _adHandler;

- (id) initWithAdHandler:(AdHandler*)anAdHandler
{
    self = [super init];
    _adHandler = [anAdHandler retain];
    return self;
}

- (void)dealloc
{    
    [super dealloc];

    [_adHandler release];
    _adHandler = nil;
}

...

@end

When stepping through the code in iOS 6, I've found that after the dealloc statement, [_adHandler retainCount] is still positive, and the object is still available.

In iOS 7 however, after the dealloc statement, retainCount has somehow hit zero, and the _adHandler object has been dealloc'd, and therefore my call to release causes an EXC_BAD_ACCESS.

I can fix this simply by moving my [adHandler release] call to before the dealloc call, but my question is why is this happening? Why is dealloc releasing objects that it has no responsibility for? Is there any documentation anywhere on why dealloc behaviour has changed in this way?

Was it helpful?

Solution

After [super dealloc] the instance is garbage and whatever happens is rather random and non-deterministic. As @bneely wrote, [super dealloc] must be last.

Best practice: convert to ARC.

As for retainCount, there are no guarantees what it's value may be, don't use it, it just caused confusion. In your case you destroyed the class instance by calling [super dealloc] and then expect the instance to behave as if it still exists. It can't, it has been destroyed and is now just some non-deterministic bits in memory.

OTHER TIPS

You should never use retain count.

The values it returns cannot be interpreted by you in any reasonable way. Thus it's entirely expected to see different results on different iOS versions, devices, with different code bitness, etc.


On a side note, do you consider switching to ARC? The code would greatly simplify. Also note that if you're implementing a subclass of UIViewController, you shouldn't initialize it with init. Rather just declare the property and ARC will take care of its setters and getters:

@interface MyViewController : UIViewController
@property AdHandler *adHandler;
@end

// somewhere else 
MyViewController * mvc = ... from nib or in some other way ...
mvc.adHandler = myAdHandler;

Now you're guaranteed no bad accesses.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top