This post is a little technical, but hopefully it will give some insight into the process of developing for iOS.
Although an iPod touch has 128 MB of RAM (recall that the original game ran on a Windows machine with 16 MB), memory is still relatively limited. Despite fitting in your pocket, it’s doing a lot more than Windows 95 — tons of multitasking to play your music, talk to the network(s), and if it’s an iPhone, handle calls or SMS while you’re in the game. And while the screen has fewer pixels, the original required only 16 bit color, and iPhone has 24 (plus alpha on the interim textures). And we couldn’t do alpha at all in the original.
iOS watches memory closely, and if an app starts getting too greedy, kills it (after sending several increasingly stern warnings). So it’s important not to use too much. But how can you tell?
I think I tweeted before how much better the development tools are than 11 years ago. Instruments is as good as anything I’ve seen and it’s part of the free Xcode tools.
Once I realized there was an issue, I first used the Leaks instrument to look for memory leaks. There weren’t any. One reason for that is Xcode comes with a great static analyzer, which can look at your source code and identify likely leaks. This is an awesome tool, because you don’t have to exercise every piece of code to find memory problems.
But a leak is defined as memory that’s allocated but can’t be accessed. It’s also possible to have accessible but useless objects, which I term “bloat” to distinguish from a true leak.
The Allocations instrument will show each memory allocation, identifying exactly what it is and where in your code it was created. It was pretty obvious that switching between management screens left the old one around. It was even easier to verify this (and make sure it was fixed) by filtering (all the management screens are implemented as UIViewControllers, so I typed “Controller” into the search field). You can see several system-created controllers, but also that there are currently three instances of the Magic screen. (The MagicController may be less than 1 KB, but it manages a host of other objects, so the impact is more serious than it may appear.)
The screen shot shows Instruments running in the Simulator, but the tools work with a device, too. The Mac-hosted simulator has far more RAM than any device, so you can’t easily use it to test for low memory conditions. But the memory allocations are the same, so I can use it for this task. (The development cycle is much faster with the simulator, since you don’t have to copy builds to a device.)
So once I could see what was going on, it was pretty easy to stop the bloat. It’s hard to know how long it would have taken to find this in the past, but definitely more than a couple hours. The great tools are just one reason I like developing for iOS.
Further Reading
Apple has good documentation, but Bill Bumgartner’s “When is a Leak not a Leak? Using Heapshot Analysis to Find Undesirable Memory Growth” is a great article on tracking down bloat with Instruments.