NULL vs nil in Objective-C
Asked Answered
I

5

194

In observeValueForKeyPath:ofObject:change:context: - why do the docs use NULL instead of nil when not specifying a context pointer?

Immunology answered 17/2, 2009 at 16:14 Comment(1)
in my opinion, object is nil, class is Nil, and NULL using for object or classRestaurant
P
233

nil should only be used in place of an id, what we Java and C++ programmers would think of as a pointer to an object. Use NULL for non-object pointers.

Look at the declaration of that method:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
    change:(NSDictionary *)change context:(void *)context

Context is a void * (ie a C-style pointer), so you'd definitely use NULL (which is sometimes declared as (void *)0) rather than nil (which is of type id).

Pennebaker answered 17/2, 2009 at 16:23 Comment(14)
But since the type of context in observeValueForKeyPath:ofObject:change:context: is void *, doesn't that mean that the data passed as the context could be an object pointer? I would think that to be a common case. That's why I'm confused as to why the docs always use NULL instead of nil.Immunology
The type of context: in that method is "void *". "nil" is not a "void *", but NULL is.Pennebaker
So is it correct to deduce from this discussion that we cannot pass an object pointer (aka, something that can be typed as nil) when we pass this message to the object implementing NSKeyValueObserving? Because object pointers cannot be of type void * ?Immunology
To be honest with you, I don't know if you can cast an id into a void*.Pennebaker
You can. void * is any pointer. Nonetheless, you are absolutely right that NULL is the correct constant there.Luganda
This gets to the meat of my question - why is NULL the correct constant in this case, rather than nil? Given that NULL and nil both have the same "value", what I want to understand is the reasons for using one vs the other - is it intended that context not be an object pointer? It seems deliberate.Immunology
They said void *. NULL is for void * and nil is for id. Therefore, you pass NULL. If you pass nil, you are lying to your reader, who will think this method takes an id.Luganda
Peter's got it exactly right - if a function expects a type, and you want to pass a null, pass in the correct null type, not one that just happens to be a subset or have the same internal representation.Pennebaker
Or to think of it another way, NULL is a broader type, and nil is a subset of NULL. In general, use the broadest type you can get away with (ie in Java, write your method to expect a Collection instead of a Vector, unless you need something specific from Vector)Pennebaker
That makes good sense. Thanks to both of you for humoring my persistent questions.Immunology
I'm glad you understand it better now.Pennebaker
As someone pretty new to the C family of languages, I didn't understand this answer until I also read the answer to this question: #1304676 Perhaps a link to that question would be a helpful addition to this answer? The semantic distinction between 'C-style pointer' and 'pointer to an object' was - to me at least - not obvious from this answer.Rohn
Do you know what is the case when a method receives a pointer to a pointer, i.e.: ...withError: (NSError **)error; ?Dower
@DanielSanchez Very late answer, but still useful for someone that may have your same question, as I once did. The double-pointer i.e. pointer to a pointer allows the callee to assign the value that NSError points to such that the caller can observe the effects. It's a simple way to return multiple values from a method without writing ugly bundling code.Baerman
E
67

They're technically the same thing (0), but nil is usually used for an Objective-C object type, while NULL is used for c-style pointers (void *).

Elasticity answered 17/2, 2009 at 16:21 Comment(4)
Also, NULL is differently defined than nil. nil is defined as (id)0. NULL isn't.Heavyweight
@WTP if you read through MacTypes.h, it declares #define nil NULLEthicize
That is very interesting. It seems it does not matter than other than for style points. It's like YES/TRUE and NO/FALSE.Fassold
@Brennan, That's not entirely true, just because nil is defined as NULL doesn't mean there's some other hidden implementation behind the scenes. For example, IBAction is defined as void but it has a different meaning when using interface builder when displaying methods to attach to actions on buttons and such.Titrant
W
54

They're technically the same thing and differ only in style:

  • Objective-C style says nil is what to use for the id type (and pointers to objects).
  • C style says that NULL is what you use for void *.
  • C++ style typically says that you should just use 0.

I typically use the variant that matches the language where the type is declared.

Wellthoughtof answered 5/11, 2009 at 13:53 Comment(0)
C
15

NULL is the C equivalent of nil, a pointer to nothing;

where nil is zero typed as id,

NULL is zero typed as void*.

One important point you can’t send a message to NULL. So it is preferred to use nil in objective-C at many places.

Camelot answered 26/7, 2013 at 6:18 Comment(0)
L
4

They almost are the same thing except,

nil is used in an Objective-C style. where NULL is for C type pointers and is typdef'ed to (void *).

Lucienlucienne answered 1/2, 2016 at 9:12 Comment(1)
Isn't this pretty much a repeat of this existing answer?Brasier

© 2022 - 2024 — McMap. All rights reserved.