+[NSURL URLWithString:] changed

There are many methods in Cocoa that, particularly when constructing an object, throw an exception if passed nil. I can empathise with the logic behind it: "you asked me for an object, but I can't comply based on the input", although it's not necessarily the friendliest thing for the frameworks to do.

NSURL is one such class. Here are some methods which at present throw an exception when handed a nil string:

  • -initWithString:
  • -initWithString:relativeToURL:
  • -initFileURLWithPath:
  • -initFileURLWithPath:isDirectory:
  • +fileURLWithPath:
  • +fileURLWithPath:isDirectory:

We then move on to two other cases:

  • +URLWithString:
  • +URLWithString:relativeToURL:

The behaviour of these methods actually depends on which SDK you link against. When running on OS X v10.6, or linking against the 10.6 SDK while running on a newer OS, they throw an exception when handed nil. Just like the other methods above.

If you link against the 10.7 SDK or newer, and are running on 10.7 or later, you instead get the more sensible & friendly behaviour of them returning nil. 

This used not to be documented, and that lack was what prompted the ranty portion of this blog post. But I'm happy to report that the NSURL documentation now properly notes this behaviour.

I'm quite keen on the idea that a class's convenience factory methods can do extra error checking to return nil before they bother calling through to +alloc. And that trying to initialise and instance with nil is more of a programmer error, so throws an exception. But it's infuriating if a change to this policy isn't documented. And then made stranger by the +fileURL… methods not adopting the same policy. So I also filed rdar://problem/12710314 asking for them to take this approach in future.

The important moral of the story here: if you're deploying to 10.6, or using the 10.6 SDK, be careful when calling +URLWithString:… that you're not ever passing in nil, as it will blow up on you, and likely not at development time.

© Mike Abdullah 2007-2015