Ben Ford

benford.me

NSArrays Are Big Fat Jerks

Those pesky crashes

Developing on the iOS platform is unique is many ways; one particularily annoying item is the way problems show themselves as a sudden crash of your app. The two most common causes of crashes of an iOS app are: 1) performing incorrect memory management, and 2) accessing NSArray outside it’s bounds. Automatic reference counting solved the first problem. That leaves us battling the unforgiving NSArray.

NSArray likes to crash

Accessing an NSArray with an index that does not exist instantly crashes your app. The NSDictionary collection, which uses keys, will return nil if you ask for element with an non-existant key. They are very different collections with totally separate use cases. For one, NSArray isn’t allowed to be sparsely filled—it must contain data in sequential format. So they are different, but this doesn’t explain why NSArray can’t simply return a nil value on non-existant indexes.

Why can’t we be friends

I’ve been plotting to create a NSArray subclass, called BFSparseArray, that will always return nil on an invalid index. It sounded like a wonderful idea until I realized why this would be very bad. Having code return unexpected values is harder to debug than a crash. The unexpected value will cause all sorts of weird behaviors, things that end up being incredibly hard to track down. The crash on the other hand halts the execution immediately, and (if you use the NSSetUncaughtExceptionHandler() trick) you get a full stack trace that directs you right to the problem.

No coddling here

So in the words of Daniel Jalkut, “Don’t coddle your code”. Let those crashes happen and keep on trucking until they’re all fixed. While you’re writing code and libraries of your own, don’t return default values if input is unexpected. It is usually better to crash the app immediately instead of obsurcing the buggy condition even further.

(By the way, NSAssert() is a nice, obvious way to check for valid input, and it will crash with a nice Assertion failure exception.)