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
?
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
.
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.
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.
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.