Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a method on an uninitialized object (null pointer)

  1. What is the normal behavior in Objective-C if you call a method on an object (pointer) that is nil (maybe because someone forgot to initialize it)? Shouldn't it generate some kind of an error (segmentation fault, null pointer exception...)?
  2. If this is normal behavior, is there a way of changing this behavior (by configuring the compiler) so that the program raises some kind of error / exception at runtime?

To make it more clear what I am talking about, here's an example.

Having this class:

@interface Person : NSObject {      NSString *name;  }  @property (nonatomic, retain) NSString *name;  - (void)sayHi;  @end 

with this implementation:

@implementation Person  @synthesize name;  - (void)dealloc {     [name release];     [super dealloc]; }  - (void)sayHi {     NSLog(@"Hello");     NSLog(@"My name is %@.", name); }  @end 

Somewhere in the program I do this:

Person *person = nil; //person = [[Person alloc] init]; // let's say I comment this line person.name = @"Mike";            // shouldn't I get an error here? [person sayHi];                   // and here [person release];                 // and here 
like image 702
Florin Avatar asked Apr 23 '10 07:04

Florin


People also ask

What happens when you call a method on a null object?

If you call a static method on an object with a null reference, you won't get an exception and the code will run. This is admittedly very misleading when reading someone else's code, and it is best practice to always use the class name when calling a static method.

What happens when you invoke a method on a nil pointer?

What happens when you invoke a method on a nil pointer? Nothing. This is important because, in Objective-C, sending a message to an object means telling that object to do something, or asking that object for some information. If the runtime system did not treat nil as a special case, it would probably crash.


2 Answers

A message sent to a nil object is perfectly acceptable in Objective-C, it's treated as a no-op. There is no way to flag it as an error because it's not an error, in fact it can be a very useful feature of the language.

From the docs:

Sending Messages to nil

In Objective-C, it is valid to send a message to nil—it simply has no effect at runtime. There are several patterns in Cocoa that take advantage of this fact. The value returned from a message to nil may also be valid:

  • If the method returns an object, then a message sent to nil returns 0 (nil), for example:

    Person *motherInLaw = [[aPerson spouse] mother];

    If aPerson’s spouse is nil, then mother is sent to nil and the method returns nil.

  • If the method returns any pointer type, any integer scalar of size less than or equal to sizeof(void*), a float, a double, a long double, or a long long, then a message sent to nil returns 0.

  • If the method returns a struct, as defined by the Mac OS X ABI Function Call Guide to be returned in registers, then a message sent to nil returns 0.0 for every field in the data structure. Other struct data types will not be filled with zeros.

  • If the method returns anything other than the aforementioned value types the return value of a message sent to nil is undefined.

like image 111
Rob Keniger Avatar answered Sep 20 '22 04:09

Rob Keniger


From Greg Parker's site:

If running LLVM Compiler 3.0 (Xcode 4.2) or later

 Messages to nil with return type | return Integers up to 64 bits           | 0 Floating-point up to long double | 0.0 Pointers                         | nil Structs                          | {0} Any _Complex type                | {0, 0} 
like image 42
Heath Borders Avatar answered Sep 23 '22 04:09

Heath Borders