How do I check if a NSNumber object is nil or empty?
OK nil is easy:
NSNumber *myNumber;
if (myNumber == nil)
doSomething
But if th
NSValue, NSNumber, ... are supposed to be created from a value and to always hold one. Testing for a specific value like 0 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 use NSNull instead.
In your first example this could be:
[dict setValue:[NSNull null] forKey:@"emptyValue"];
if ([dict objectForKey:@"emptyValue"] == [NSNull null]) {
// ...
}
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":
if ([dict objectForKey:@"nonExistent"] == nil) {
// ...
}
As for the second example, -intValue gives you 0 - but simply because sending messages to nil returns 0. You could also get 0 e.g. for a NSNumber whose intValue was set to 0 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":
// add if not empty:
[dict setObject:someNumber forKey:someKey];
// remove if empty:
[dict removeObjectForKey:someKey];
// retrieve number:
NSNumber *num = [dict objectForKey:someKey];
if (num == nil) {
// ... wasn't in dictionary, which represents empty
} else {
// ... not 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 has NSNull for such cases:
// set to number if not empty:
[dict setObject:someNumber forKey:someKey];
// set to NSNull if empty:
[dict setObject:[NSNull null] forKey:someKey];
// retrieve number:
id obj = [dict objectForKey:someKey];
if (obj == [NSNumber null]) {
// ... empty
} else {
// ... not empty
NSNumber *num = obj;
// ...
}
This option now allows you to differentiate between "empty", "not empty" and "not in the container" (e.g. illegal key).