How do I check if a NSNumber object is nil or empty?
OK nil is easy:
NSNumber *myNumber;
if (myNumber == nil)
doSomething
But if the object has been created, but there is no value in it because an assignment failed, how can I check this? Use something like this?
if ([myNumber intValue]==0)
doSomething
Is there a general method for testing objects on emptiness like for NSString available (see this post)?
Example 1
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:@"" forKey:@"emptyValue"];
NSNumber *emptyNumber = [dict objectForKey:@"emptyValue"];
Which value does emptyNumber
contain? How can I check if emptyNumber
is empty?
Example 2
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:@"" forKey:@"emptyValue"];
NSString *myString = [dict objectForKey:@"emptyValue"];
if (myString == nil || [myString length] == 0)
// got an empty value
NSNumber *emptyNumber=nil;
What happens if I use this after emptyNumber
was set to nil?
[emptyNumber intValue]
Do I get zero?
Example 3
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:@"" forKey:@"emptyValue"];
NSNumber *myEmptyValue = [dict objectForKey:@"emptyValue"];
if (myEmptyValue == nil)
// NSLog is never called
NSLog(@"It is empty!");
Like this way NSLog is never called. myEmptyValue
is not nil
and not NSNull
. So it contains an arbitrary number?
Best Answer
NSValue
,NSNumber
, ... are supposed to be created from a value and to always hold one. Testing for a specific value like0
only works if it isn't in the range of valid values you are working with.In the rare case where code is more straight-forward to work with if you have a value that represents "invalid" or "not set" and you can't use
nil
(e.g. with the standard containers) you can useNSNull
instead.In your first example this could be:
But note that you can simply not insert (or remove) that value unless you need to differentiate
nil
(i.e. not in the container) and, say, "invalid":As for the second example,
-intValue
gives you0
- but simply because sending messages tonil
returns0
. You could also get0
e.g. for aNSNumber
whoseintValue
was set to0
before, which could be a valid value.As i already wrote above, you can only do something like this if
0
is not a valid value for you. Note the for you, what works best completely depends on what your requirements are.Let me try to summarize:
Option #1:
If you don't need all values from the numbers range, you could use one (
0
or-1
or ...) and-intValue
/ ... to specifically represent "empty". This is apparently not the case for you.Option #2:
You simply don't store or remove the values from the container if they are "empty":
This however means that there is no difference between keys that are empty and keys that never exist or are illegal.
Option #3:
In some rare cases its more convenient to keep all keys in the dictionary and represent "empty" with a different value. If you can't use one from the number range we have to put something differently in as
NSNumber
doesn't have a concept of "empty". Cocoa already hasNSNull
for such cases:This option now allows you to differentiate between "empty", "not empty" and "not in the container" (e.g. illegal key).