7

I find some time ago the enum kNilOptions which is equal to 0. I try to make my code the most readable but I wonder what is best to use when you have methods that take an option parameter, for example :

[NSData dataWithContentsOfFile:imageURL.path
                               options:kNilOptions
                               error:&error];

I usually see nil in a lot of code I read but I think kNilOptions would be more accurate. I don't see often (almost never) kNilOptions. Is there a reason for that?

Do you think it is ok to use it or is it better to stick to simply nil?

Kevin Hirsch
  • 956
  • 1
  • 9
  • 17
  • 1
    AFAIK, but I might be wrong, kNilOptions is from MacTypes.h or similar, and is very old and obsolete. It seems that Apple prefers 0 or nil. Take a look at all the examples. They never use kNilOptions. – Rudy Velthuis Jul 15 '14 at 12:29

4 Answers4

5

I think 0 is more readable than kNilOptions and there is some evidence that kNilOptions is "old".

You should use nil to represent uninitialized Objective-C object references and NULL for uninitialized C pointers (void *, char *, etc).

Use 0 if the options doesn't provide a "none value", which is the case for options NSDataReadingOptions.

Iulian Onofrei
  • 9,188
  • 10
  • 67
  • 113
trojanfoe
  • 120,358
  • 21
  • 212
  • 242
  • 1
    AppCode will raise some warnings if you simply use '0'. Better use `kNilOptions` to explicitly state you are using an Enum value. http://stackoverflow.com/a/34624671/1033581 – Cœur Jan 06 '16 at 05:20
  • @Cœur Sounds like AppCode is broken. – trojanfoe Jan 06 '16 at 07:23
  • 1
    Doesn't mean it's broken, it means `0` is not suitable for an Enum value, just like `0` is not suitable for an object reference. – Cœur Jan 06 '16 at 07:26
  • @Cœur If the compiler is happy with the code but the IDE is not, then the IDE is broken. – trojanfoe Jan 06 '16 at 07:53
  • But `0` is not at all clear as `kNilOptions` is. For example, good luck searching your entire project for places where you didn't specify an option. – Iulian Onofrei Aug 08 '19 at 09:09
4

kNilOptions is an old constant intended to document that the 0 is not just any magic zero, but stands for “no options”. In that sense its use is valid, although personally I consider it quite ugly in an Objective-C context (most of its use seems to be in C) with the k prefix and all. Searching developer.apple.com for options:kNilOptions vs options:0 also shows that options:0 is their preferred style.

As for nil, it is the Objective-C equivalent of a null pointer for objects, and should not be used to stand in for the number 0 (as would be the case here).

When the argument is an enum type that includes its own “no options” value, you should use that, but in case of NSData the argument is not an enum but a typedef'd NSUInteger, and it does not have its own “no options” value defined.

Arkku
  • 41,011
  • 10
  • 62
  • 84
1

Even if Apple uses it, AppCode will warn you if you simply use 0 for an NSEnum/NSOption value, as you are using an integer instead of an Enum value.

So you need to either explicitly cast 0 to the correct Enum type:

[NSData dataWithContentsOfFile:imageURL.path
                       options:(NSDataReadingOptions)0
                         error:&error];

Or use kNilOptions which is an anonymous Enum value:

[NSData dataWithContentsOfFile:imageURL.path
                       options:kNilOptions
                         error:&error];

I recommend the later solution, kNilOptions instead of (NSDataReadingOptions)0, to avoid manually written C-cast.


The same issue arises for object pointers.

You need to either explicitly cast 0 to a pointer:

[NSData dataWithContentsOfFile:imageURL.path
                       options:readOptionsMask
                         error:(void*)0];

Or use nil which is a cast to a pointer itself:

[NSData dataWithContentsOfFile:imageURL.path
                       options:readOptionsMask
                         error:nil];

Everybody would recommend the later solution, nil instead of (void*)0, to avoid manually written C-cast.

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • `nil` is not correct as it represents an Objective-C object that points to nothing. In the context of the `error:` parameter, it's a pointer to an Objective-C object pointer and so should conventionally be `NULL`. The fact that AppCode cannot cope with a syntax that Xcode can, hints that AppCode is broken and coders should not have to change to work-around it's inadequacies. – trojanfoe Jan 07 '16 at 07:21
0

Various things that can end up being a zero are used for different purposes. Not using the correct one may not affect the code, but anyone reading your code will be suspicious and will get stuck verifying that the code does make sense.

  • 0 = the integer zero.

  • 0.0 = the double precision floating point number zero.

  • '\0' = the nul char, which is used as the delimiter of a C string.

  • NULL = a C or C++ pointer that doesn't point to anything.

  • nil = an Objective-C object pointer that doesn't point to any object (As an implementation detail, nil == 0 just happens to evaluate to true, but don't use nil instead of 0/false).

  • Nil = an Objective-C class pointer that doesn't point to any class.

  • kNilOptions (in this case) = an enumeration constant describing that there are no options.

Nicolas Miari
  • 16,006
  • 8
  • 81
  • 189
gnasher729
  • 51,477
  • 5
  • 75
  • 98