Assumptions != NSNotFound

I couldn’t figure out why an equivalent of this code:


kept having a bunch of crashes in “String was found, do stuff” section of the code in Hum.

Turns out, messages to nil which return a struct will return with all of the members of the struct initialized to zero. If passedInVariable was nil, rangeOfString would be {0,0} instead of {0, NSNotFound}, as I was assuming.

This meant that a nil receiver would cause the result fall into the if case instead of the else case, as I’d intended.

There are some cases where this would match expected behavior. For example, trying to get the frame of a nil view would return a struct which would be equal to CGRectZero.

But particularly when you’re looking for either an NSNotFound or some other non-zero “nope, it ain’t here” value, this is a pretty solid gotcha in Objective-C.

This is a good reason to use the (presently not in the NSString documentation but in the header file) containsString: method on NSString instead of this technique if you’re on 8 or above, since that will return NO if you message a nil object.

And as was pointed out several times in response to my facepalming twitter post on this: This case is a crystal-clear example of why optionals make Swift an inherently safer language than Objective-C.

(Thanks to Daniel Jalkut for pointing me to a useful reference on what happens when you message a nil object) given assorted return types.