Skip to content

Archive

Tag: NSZombieEnabled

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.

Activity log

  • Last weekend (June 21st) I was very busy working on fixing memory leaks in my apps. I’d profiled the product  using ObjectAlloc before, that doesn’t really help fixing leaks per se, but it does help making sure that the app doesn’t run out of memory.
    So why I am fixing the leaks? I’m not sure. For a while I was just worried my app might get rejected because of having so many leaks. But then I’m an either/or person at times. Either fix all of the leaks I can find, or don’t fix any.
    Yea. Now you’re asking why I need to think whether I should fix leaks or not? Well, when you’re in a genuine multitasking environment and your app is running for a long long time, you have to fix the leaks. If you’re writing a game and it can already run for 4 times the expected maximum playtime, in my humble opinion you’re just trying to make your game crash and wasting your time by fixing something that already works .

    That is exactly what I’ve been doing.

  • A side effect of fixing leaks is over-releasing memory. Unfortunately, while leaks don’t do much harm except killing memory over time, over-releasing causes random crashes.
    TIP: right click on your executable in the project browser; select get info and choose the Arguments tab. add the following environment variable: NSZombieEnabled and set its value to YES. That will help you with zombies (if you don’t know  what that is, search NSZombieEnabled. This will help you fix random crashes.
  • This week I got busy getting an artist to help me with promotional material, not the least, my app icon. Can’t wait to see what she’s up to.
  • This week-end I’ve been internationalizing my app.

Babelize?

Earth doesn’t speak English

I’ve got about 2000 words worth of dialogues and other text bits. Not counting the app store blurb.
I’m planning on localizing in French, Chinese and Japanese (sure, english is the default). So I got into the plist xml format.
I read a post somewhere which seems to indicate you get 50% extra sales when localizing to French. So I guess translation is worth it.

Translators don’t speak XML

Humanly readable? I doubt; in my previous company programmers ended doing the translation and, retrospectively that may have been a reasonable (albeit expensive and somehow despicable) choice. XML is not quite humanly readable.

So I extracted all the text and made it look like a movie script. Then I wrote a java parser to read the script and re-write it as plist-xml, topping all that with a translation component wrapping the plist.

Does this room understand Chinese?

Boring stuff if you ask me, but seems it’s well worth it:

  • Test driving the system, the translator made only 4 mistakes, accidentally deleting a colon here and there. I could fix the mistakes in minutes.
  • Having the dialogs hard-wired in the game code was OK. For drafting stuff it’s kind of fast. But having them removed from the game code not just clarifies stuff, it also helps me normalize talk-back occurrences (picking an item, sighting an important NPC etc…)
  • It’s OK for translators to edit the text using about anything. Interestingly, we can even use word (or whatever word processor) to protect the text that shouldn’t be translated. Then paste everything back in a plain text editor, feed it into the parser and enjoy

My internet is snailing again. So I’ll provide references about all this stuff later.