In observeValueForKeyPath:ofObject:change:context:
- why do the docs use NULL
instead of nil
when not specifying a context pointer?
-
in my opinion, object is nil, class is Nil, and NULL using for object or class – Thanh Vũ Trần Nov 09 '12 at 01:45
5 Answers
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
).

- 143,310
- 32
- 282
- 281

- 179,021
- 58
- 319
- 408
-
3But 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`. – erikprice Feb 17 '09 at 16:38
-
2The type of context: in that method is "void *". "nil" is not a "void *", but NULL is. – Paul Tomblin Feb 17 '09 at 16:47
-
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 *` ? – erikprice Feb 17 '09 at 17:27
-
To be honest with you, I don't know if you can cast an id into a void*. – Paul Tomblin Feb 17 '09 at 17:57
-
3You can. void * is any pointer. Nonetheless, you are absolutely right that NULL is the correct constant there. – Peter Hosey Feb 17 '09 at 18:16
-
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. – erikprice Feb 17 '09 at 18:46
-
3They 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. – Peter Hosey Feb 17 '09 at 18:50
-
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. – Paul Tomblin Feb 17 '09 at 18:53
-
13Or 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) – Paul Tomblin Feb 17 '09 at 18:56
-
That makes good sense. Thanks to both of you for humoring my persistent questions. – erikprice Feb 17 '09 at 21:11
-
-
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: http://stackoverflow.com/questions/1304176/objective-c-difference-between-id-and-void 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. – Mark Amery Jun 28 '13 at 16:45
-
Do you know what is the case when a method receives a pointer to a pointer, i.e.: ...withError: (NSError **)error; ? – Daniel Sanchez Feb 11 '15 at 15:44
-
@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. – cincy_anddeveloper Jul 08 '20 at 15:32
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 *).

- 40,399
- 3
- 75
- 82
-
8Also, `NULL` is differently defined than `nil`. `nil` is defined as `(id)0`. `NULL` isn't. – Aug 18 '11 at 15:40
-
16
-
1That is very interesting. It seems it does not matter than other than for style points. It's like YES/TRUE and NO/FALSE. – Brennan May 01 '13 at 19:49
-
1@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. – Micaiah Wallace Mar 13 '15 at 15:49
They're technically the same thing and differ only in style:
- Objective-C style says
nil
is what to use for theid
type (and pointers to objects). - C style says that
NULL
is what you use forvoid *
. - C++ style typically says that you should just use
0
.
I typically use the variant that matches the language where the type is declared.

- 1,337
- 12
- 11
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.
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 *)
.

- 332
- 3
- 16
-
1Isn't this pretty much a repeat of [this existing answer](http://stackoverflow.com/questions/557582/null-vs-nil-in-objective-c/557607#557607)? – Pang Feb 02 '16 at 01:46