Chasing bugs isn’t always fun. When I got back to it after my first release, a few useful tools went missing and I didn’t immediately realize it. Here’s at least 3 tools/functions that you want to use in development:
- NSAssert – get your code to fail fast and report when a bad condition occurs.
- NSLog – dump text to the console
- NSZombieEnabled – an environment variable that gets really helpful to detect zombies.
You might want to disable NSAssert. NSAssert will crash your app immediately when a condition isn’t met (useful in development). I feel biased about disabling NSAssert when in production mode. First, none of your asserts should ever fire by the time you release to the app store. Second, if an assert did/should fire, what next… Well, either you have a fallback mechanism ready – then you probably don’t want a live app to crash at that point. Or (common case) you don’t have a fallback mechanism. Then what? Most likely, your app will crash anyway. So you will get a crash log, but that crash log might tell you nothing about the error.
You surely want to disable NSLog. NSLog is just wasted processing time and shouldn’t be used in production mode.
I’m not sure whether NSZombieEnabled needs to be disabled before shipping to the app store. My guess is, it’s a runtime setting, shouldn’t be passed to your app when running from iOS desktop anyways…
Code to conditionally disable NSAssert, NSLog.
If you put the following code in your *.pch file, NSAssert, NSLog get disabled when building for release – as a side effect of the __OPTIMIZE__ flag being set.
#ifndef __OPTIMIZE__
#define NSLog(…) NSLog(__VA_ARGS__)
#else
#undef NSAssert
#undef NSAssert1
#undef NSAssert2
#define NSAssert(x,y)
#define NSAssert1(x,y,z)
#define NSAssert2(x,y,z,w)
//
#define NSLog(…) {}
#endif
Beware that you don’t put code that actually does something inside your asserts. That probably looks like a no brainer, but it’s actually quite easy to accidentally paste a function call that returns a BOOL inside an assert, and forget that once the assert is removed, the call is being skipped. By any means, if you use the above code, regression test at least once in release mode before shipping your app.
Macros are evil! Welcome to the dark side.


Comments