iphoneiosautomatic-ref-countingnszombieenabled

Why is object not dealloc'ed when using ARC + NSZombieEnabled


I converted my app to ARC and noticed that an object alloc'ed in one of my view controllers was not being dealloc'ed when that view controller was dealloc'ed. It took a while to figure out why. I have Enable Zombie Objects on for my project while debugging and this turned out to be the cause. Consider the following app logic:

1) Users invokes action in RootViewController that causes a SecondaryViewController to be created and presented via presentModalViewController:animated.

2) SecondaryViewController contains an ActionsController that is an NSObject subclass.

3) ActionsController observes a notification via NSNotificationCenter when it is initialized and stops observing when it is dealloc'ed.

4) User dismisses SecondaryViewController to return to RootViewController.

With Enable Zombie Objects turned off, the above works fine, all objects are deallocated. With Enable Zombie Objects on ActionsController is not deallocated even though SecondaryViewController is deallocated.

This caused problems in my app b/c NSNotificationCenter continues to send notifications to ActionsController and the resulting handlers cause the app to crash.

I created a simple app illustrating this at https://github.com/xjones/XJARCTestApp. Look at the console log with Enable Zombie Objects on/off to verify this.

QUESTION(S)

  1. Is this correct behavior of Enable Zombie Objects?
  2. How should I implement this type of logic to eliminate the issue. I would like to continue using Enable Zombie Objects.

EDIT #1: per Kevin's suggestion I've submitted this to Apple and openradar at http://openradar.appspot.com/10537635.

EDIT #2: clarification on a good answer

First, I'm an experienced iOS developer and I fully understand ARC, zombie objects, etc. If I'm missing something, of course, I appreciate any illumination.

Second, it is true that a workaround for this specific crash is to remove actionsController as an observer when secondaryViewController is deallocated. I have also found that if I explicitly set actionsController = nil when secondaryViewController is dealloc'ed it will be dealloc'ed. Both of these are not great workaround b/c they effectively require you to use ARC but code as if you are not using ARC (e.g. nil iVars explicitly in dealloc). A specific solution also doesn't help identify when this would be an issue in other controllers so developers know deterministically when/how to workaround this issue.

A good answer would explain how to deterministically know that you need to do something special wrt an object when using ARC + NSZombieEnabled so it would solve this specific example and also apply generally to a project as a whole w/o leaving the potential for other similar problems.

It is entirely possible that a good answer doesn't exist as this may be a bug in XCode.

thanks all!


Solution

  • Turns out it is an iOS bug. Apple has contacted me and indicated they've fixed this in iOS 6.