There are many methods in Cocoa, particularly when constructing an object, that 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:
The file URL methods are documented to do this, but no such mention is made for the -initWithString:… methods. I've filed rdar://problem/12710235 asking for this to be cleared up.
We then move on to two other cases:
- +URLWithString:
- +URLWithString:relativeToURL:
Once again it's not in the URL documentation, but 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 change doesn't even get a mention in the Foundation release notes! rdar://problem/12710235 covers it too.
Presumably, iOS went through a similar change at some point too. Can anyone nail down if it was version 4, 5, or something else?
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 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.