One of the most useful tools available when developing for the non-garbage-collected iOS is NSZombie. NSZombie intercepts messages to deallocated objects (see CocoaDev’s article on NSZombie for the nitty-gritty) and can help you quickly identify the source of errors resulting from releasing an object too early or too many times, including the dreaded “SIGABRT” error. Imagine that you have just received the error below due to a (probably not quite as glaringly obvious) memory management issue:
Step One: NSZombie can help! But first, one very important thing you will need to do in order to successfully use NSZombie is to target the iPhone or iPad simulator. Before going any further make sure that you have switched from targeting your device to targeting the simulator.
Step Two: Once you have chosen the appropriate simulator for your app, click and hold on the Build/Action button to get the drop-down menu displayed in the screenshot below. Instead of “Build for Running” you will want to choose “Build for Profiling”.
Step Three: After choosing “Build for Profiling” you should see the helpful profile template picker for Instruments. While these are all useful options and hopefully you are making use of them already, the one that you want in this case is appropriately named “Zombies”. Note that if you do not see the option for Zombies you should return to step one and ensure that you have chosen a simulator as your target. This the most common hiccup that people encounter when trying to make use of NSZombie.
Step Four: After clicking profile you will see the main instruments window as well as a simulator interface. Use the simulator to recreate the issue you have been experiencing, but this time instead of a cryptic exception message in Xcode you will get a pop-up in Instruments with details about the over-released object. Clicking the small grey array on that dialog will take you to a history of that object showing you all of the memory management actions taken against that object from release to crash. This trace should hopefully give you everything you need to root out the issue once and for all. In our case we can see that we manually released an object from an autorelease pool, thereby causing an exception when the pool was drained.
That’s it! Happy coding.
– David Brainer-Banker, Software Engineer at eimagine in Indianapolis, IN