As you can clearly see from the code it's perfectly acceptable in Objective-C to send a message to nil. This is a powerful feature that prevents the program from crashing but it is confusing for beginners.
It doesn't seem particularly confusing. It's pretty much the first thing you learn: square brackets send a message, and if there's no recipient, the return value will be zero. (Granted, it used to be more complicated in the PowerPC era, when e.g. a selector that returns a double was not guaranteed to return 0.0 with a nil receiver, but those cases were fixed in the runtime.)
I suspect the messaging-to-nil behavior is mostly confusing to intermediate programmers who only have experience with Java's passive-aggressive null references.
There is no "natural" behavior to a beginner. Either way has to be learned and understood. Nil messaging behavior is only going to be confusing to people who learned one way and internalized it enough to think of it as "the way", then were exposed to the other way. Java programmers going to ObjC will find ObjC's nil handling confusing, and ObjC programmers going to Java will find Java's null handling confusing.
It's a trade-off, because it's convenient to not have to check that objects are non-nil when you send messages to them. With experience, you learn to deal with code that requires non-nil objects via assertions:
Well, you have to learn what the "zero value" for each and every type is in order to fully understand the language semantics. IMHO, this adds complexity beyond null pointer exceptions.
You also need to understand "zero values" to understand what a freshly created object looks like (all of its instance variables are initialized to zero). So I don't think it would make Objective-C any easier to learn if messaging to nil would throw an exception.
Personally I find that the nil behavior provides a useful base guideline for API design. When defining a method signature in Obj-C, you have to ask yourself if it's clear to the user of the method what happens when the method (inevitably) gets sent to nil. In that way, you have to think about the circumstances of the API's actual use, rather than just the ideal case.
Yes, thanks! (I still haven't learned the English names for the various brackets, it seems... In my mind, the ones with the straight angles are the "angle" ones.)
And for those learning etymology, parenthesis comes from ancient Greek:
Parenthesis, from "para" (next, beside, near) and "enthesis" (embedd, inline). So, essentialy to "inline near/next to something" (what we do with a parenthetical phrase).
The ability to send messages to nil is not only there to prevent crashes. It can also be used to make clean APIs or to use APIs with a lot of convenience. It also gives you a lot of flexibility... It allows you to do the error handling on a case by case basis. If you are not interested in erros simply do not check for nil and go on...