Debugging Objective-C on the iPhone is usually OK, but there are some painful moments with those hard to find bugs. Today’s bug went something like this:
1.) Open iPad app in portrait mode
2.) Click on “My Blogs” top left and choose a blog
3.) Make sure you are on the comments view and click ‘edit’ at the top right of that dialog (the button changes to ‘cancel’)
4.) Then when the list is in edit mode rotate the device to landscape mode
5.) The ‘cancel’ button now says ‘edit’. click on this ‘edit’ button.
6.) It should work fine, now simply put the device in portrait mode again and continue from step 2 above.
It should crash the second time you do this, if not it will crash on the third time.
Nice catch. When you are debugging with Xcode, most of the times you get some useful message in the console or at least some stack trace pointing where things went wrong. Today’s message was this useful
Program received signal: “EXC_BAD_ACCESS”.
And the stack trace was no better:
If you have worked with Cocoa for a while, you might be familiar with NSZombie, but since the development tools have changed in the last years, some of the tutorials around are not accurate.
NSZombie is a Cocoa trick that turns any object going to be deallocated into a NSZombie instance. You are going to crash anyway, but instead of Xcode just complaining that you tried to access the wrong memory address, you get something a bit better like this:
2011-02-25 01:27:57.063 WordPress[10496:207] *** -[CFString isEqualToString:]: message sent to deallocated instance 0xcf1b0c0
Not much, but at least you know that the guilty object was a string.
But there’s more to it. First, you enable NSZombie by double clicking your executable in the project info, and then in the “Arguments” tab setting the NSZombieEnabled environment variable
Instruments, that wonderful tool
Sometimes, it will be enough just knowing which class was released more than it should. But when it’s not, Instruments can help.
Sadly, Instruments can only do NSZombie magic on the simulator, but for this example that was not an issue. From Xcode, go to the “Run” menu, then “Run with Performance Tool”, and there you’ll probably see Zombies disabled. Don’t worry, select “Allocations” and you will be fine.
As soon as the app starts running, stop it by clicking on the big record button, we need to set up a few things first.
Click on the little “info” button besides Allocations, and enable “Record reference counts” and “Enable NSZombie detection”. Start the app again (with the same big record button) and repeat the steps that led to the crash. Same story, but this time…