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?
NSValue,NSNumber, … are supposed to be created from a value and to always hold one. Testing for a specific value like0only 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 useNSNullinstead.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,
-intValuegives you0– but simply because sending messages tonilreturns0. You could also get0e.g. for aNSNumberwhoseintValuewas set to0before, which could be a valid value.As i already wrote above, you can only do something like this if
0is 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 (
0or-1or …) 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
NSNumberdoesn’t have a concept of “empty”. Cocoa already hasNSNullfor such cases:This option now allows you to differentiate between “empty”, “not empty” and “not in the container” (e.g. illegal key).