What does sending a message to zero mean, and why is this a special case?

I just started reading Objective-C tutorials, and there is a section on "posting messages to nil ":

Cocoa has several patterns: that use this fact. the value returned from the message in nil may also be valid:

What does it mean? I can not follow him.

+4
source share
5 answers
  • nil is basically a null pointer (i.e., this is the zero stored in the pointer).
  • All messages in nil are legal (they will not fail), but they do nothing.
  • All nil messages return nil, or 0, or 0.0, or NO, depending on the type of return.
+9
source

Special nil handling means you can do the following:

 SomeClass * someObject; someObject = nil; [someObject doSomething]; 

And you can be sure that nothing will happen.

Now why is this important?

In Objective-C, sending a message to an object means telling the object to do something, or requesting that object for some information. Some examples:

 [someObject updateRecords]; // 1 x = [someObject size]; // 2 

Line 1 sends someObject message called updateRecords , and line 2 sends a message with the name size to the same object, which is expected to return a value. These messages come down to method calls, and the actual code that ends with the run is determined by the Objective-C runtime system, since Objective-C is a dynamically typed language.

To determine which method to call, the runtime reads information from the address of the object in question ( someObject , in the examples above) to determine which class is an instance. Using this information, he can look for the appropriate method to call, and when everything that has been found out, it runs the code in the method.

If the runtime system did not consider nil as a special case, it is likely to crash if you try to execute the code shown at the top. nil defined as zero, so the runtime will begin to read information from the address stored in the zero location in memory, which is almost guaranteed to violate access rights.

+8
source

You can send any message to zero. Nothing has happened.

What exactly do you not understand in these documents?

+5
source

The great thing about nil messaging compared to other languages ​​like C # is that you can write code that executes multiple method calls without having to check for zero at every step.

 id obj1 = [SomeClass object]; id obj2 = [obj1 doSomething]; id obj3 = [obj2 anotherMethod]; id thingICareAbout = [obj3 doSomethingElse]; 

If you go through several steps to get to thingICareAbout , it will save a lot of unnecessary lines of code so as not to test if obj1, obj2, etc. are nil before using them. You can simply check if thingICareAbout is zero at the end if you need to. Sometimes you don’t even need to do this if your code still works when it is zero (or 0 for primitive values).

In C #, you would have to explicitly check if every object in nil is there, configure exception handling around this block of code, or just hope that none of the intermediate objects will ever be zero.

Another thing to keep in mind (which I just found out myself!) Is that 10.5 changed this behavior - it used to be that it was safe only for integers and pointers to objects, not to structures or floating point values. Because of this, you may see additional error checking when you look at other code.

+2
source

He does what you expect: nothing.

+1
source

All Articles