Lessons for the Beginning iPhone Developer
Getting started with iPhone development can be an intense process. If you’re not coming from the world of OSX development, you’re probably more familiar with the myriad languages that look more like C++ than Smalltalk, and you have a lot of new syntactical things to learn, with square-brackets in abundance. It can be easy to focus completely on learning the syntax of Objective-C, and forget that the iPhone is a device with more severe limits on resources than computers, and that you will ultimately have to get your app approved by Apple before you can distribute it, so you need to follow their guidelines to the letter.
Following are some lessons indented for developers who are well versed in any number of other programming languages, but who are coming to the iPhone for the first time.
Memory Management
This one is huge, and easy to underestimate. Don’t develop your entire application and then decide to check to see if you have any memory problems. The iPhone has about 128 MB of volatile memory on board, and the virtual memory model does not include swap space. This means that, even though your iPhone has 8GB or 16GB of Flash storage, memory that your application allocates will not be swapped out to the disk to free up system memory. Since over-releasing objects will crash an application in often difficult to understand ways, it can be tempting to never release objects. However, the system monitors memory usage, and shuts down any application that takes up too much memory. This is the cause of a great many application crashes on the iPhone. You can use around 30 MB safely. Get closer to 40 or 50, and the system will very likely shut your app down with an exit status of 101.
Technically speaking, the system monitors total memory usage in order to maintain continuity of critical applications, such as the phone system, the audio system, and other systems that run constantly on the phone. When total memory usage climbs high enough that the functionality of these systems is put in jeopardy, the application currently on top of the stack will be shut down. This does mean that it is possible for one of these background processes to be using too much memory, causing your app to be shut down. Shutting down the phone and restarting usually takes care of these sorts of conditions.
Definitely read and understand the Memory Management Programming Guide for Cocoa, it’s one of the most important documents to read.
Generally, the Memory Management guide can be summed up by saying that you must release any object that you create with alloc, new, or copy, or one that you have specifically retained with retain.
Human Interface Guidelines
Read and understand the Apple Human Interface Guidelines. Apple calls this document “required reading” for a reason. They’re not being allegorical. Failure to follow the guidelines has resulted in many apps being rejected from the app store. You can always resubmit, of course, but resubmitting means you’ll have to wait for your app to be approved again.
Understanding the Review Process
Before you can distribute your app on the App Store, you’ll have to submit the app to Apple for review. This can take anywhere from a few days to…unfortunately…a few months. Most apps will get some sort of response from Apple within a week. These responses fall into three categories:
- Approved: Hooray! Your app will appear in the App Store shortly.
- Rejected: Unless your app has been deemed inappropriate for the app store, you will be given a list of items to fix. Fix them and resubmit for approval.
- Unexpected Additional Time to Review: This is bad. iPhone developer forums are full of stories of apps that have gotten this feedback, and have been stuck in the queue for months to follow. It may be a good idea to resubmit your app at this point and hope for another reviewer. I haven’t found any definitive answers on what the best course of action is when this happens.
Exception Breakpoints
By default, exceptions are not very easy to trace in XCode. This is a pain because it makes it impossible to debug application crashes. Luckily, the solution is pretty simple. Adding a global breakpoint for “obj_exception_throw” and “–[NSException raise]” will cause XCode to break on exceptions, allowing the stack trace to be viewed. Global breakpoints can be added in XCode under Run => Show => Breakpoints.
“malloc_error_break” can be used to obtain information on a malloc error.
Zombies!
Over-releasing objects can cause difficult to track down problems, usually resulting in an EXC_BAD_ACCESS exception. Setting the NSZombieEnabled environment variable will dynamically change the class of deallocated objects to _NSZombie rather than actually freeing the memory. This does mean that memory is never freed, so obviously, this isn’t something to be left on all the time, but it can come in handy when trying to track down over-releases and premature releases. NSZombieEnabled is set by editing the Active Executable, and adding an Environment Variable named “NSZombieEnabled” with a value of “YES”.
GDB Console Commands
Debugging in XCode is frustrating until you realize the power of GDB in the console. Set a breakpoint in your code, and you can learn all sorts of things with these commands:
- print (unsigned int)[someObject retainCount]
- display the retain count of an object
- print (unsigned int)[[someObject size] retain]
- Show the size of an object. The retain is necessary to keep the object from being released here.
- po someObject
- display information about an object. In the case of an NSString, the string will be printed.
- po [someView subviews]
- Print an array of subviews of a view.






