0

I was reading a question asked about the difference between NULL and nil in objective-c, found here: NULL vs nil in Objective-C

I'm not sure if understood the difference completely. I understood that NULL should be use for C-style pointers and nil for id and object pointers.

I've been reading "Programming in Objective-C Fourth Edition" by Stephen Kochan. Some of the of the code samples in the book go against what was described in the question above.

For example:

One code sample creates a method that returns an NSMUtableArray where he tries to populate an NSMutableArray, if the Array is empty in the end he returns nil:

-(NSMutableArray *) someMethod
{
  NSMutableArray *arr = [NSMutableArray array];

  //try to populate arr

  if([arr count])
  {
    return arr;
  }
  else
  {
    return nil;
  }
}

Later on in a different code sample, he uses NULL for a pointer object

{
   NSFileManager *fm = [NSFileManager defaultManager];
   [fm copyItemAtPath: @"some file path" error: NULL]
}

Looking the NSFileManager documentation, it says to pass in nil for the NSError pointer if error information isn't wanted.enter image description here

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/index.html#//apple_ref/occ/instm/NSFileManager/copyItemAtPath:toPath:error:

Community
  • 1
  • 1
Amre
  • 1,630
  • 8
  • 29
  • 41
  • 1
    All Objective-C objects are used as pointers, and not as values. So the type of an object is always `SomeType*`. The reason `NULL` is used in your example is that it's a double pointer, not just a single pointer. Another way to think of it might be that you usually use `NULL` where it might be dereferenced, and `nil` where it won't be. – ahruss Nov 22 '14 at 20:51

2 Answers2

1

The code samples you cited use it correctly. NSMutableArray * is an Objective-C object pointer type. So we use nil. On the other hand, the second parameter to copyItemAtPath:toPath:error: has type NSError **, which is not an Objective-C object pointer type. It is a regular C pointer to the pointer type NSError * (NSError * is an Objective-C object pointer type; however, a pointer to it is not). So we use NULL.

Basically, it depends on "pointer to" what. NSMutableArray * is pointer-to-ObjC-object type. On the other hand, NSError ** is a pointer-to-pointer type. Pointer-to-pointer, and pointer-to-primitive, and pointer-to-anything-else, are regular C pointers. Note that only Objective-C object pointer types are managed in ARC.

As for the documentation, I believe it is due to the addition of Swift. Before Swift, the old documentation said NULL. In Swift, the various C pointer types also use nil (which is a general constant which can be a value of any type that conforms to NilLiteralConvertible) for null pointer.

newacct
  • 119,665
  • 29
  • 163
  • 224
0

Essentially because memory is now all managed by ARC you could get away with using either or in your code. However, nil is for all Objective-C objects e.g. NSError whilst NULL is for C style things like (void*).

Rob Sanders
  • 5,197
  • 3
  • 31
  • 58