问题
First off I confess my ignorance, I've learned everything I know about Objective-C in the few months I've been working on my project. I also find it utterly frustrating how Objective-C seems to complicate what would be simple matters in any other language I've worked with. This question is a case in point...
In the first run my app downloads a bunch of JSON which it uses to populate a CoreData store. I use an Obj-C/JSON library (CJSONDeserializer) to convert the JSON to NSArrays. In the JSON download for one CoreData entity there's a field containing a number ("show_id":2
) identifying the related field in another entity if there is one or null ("show_id":null
) otherwise. In processing that field I assign it to an NSNumber using...
NSNumber *shoIndex = [[item objectForKey:typeKey] objectForKey:@"show_id"];
I then try to check that I have a valid number before attempting to fetch & link the related record so as to not do wasteful processing where there is no related record.
Interrogating shoIndex
with...
NSLog(@"shoIndex: %i, %@, %@", shoIndex, shoIndex, [shoIndex description]);
Gives...
shoIndex: 19590600, <null>, <null>
where the JSON value was null
&...
shoIndex: 228300880, 51, 51
otherwise.
So far the only successful check I've made is with...
if (![[shoIndex description] isEqualToString:@"<null>"]) {
Can anyone suggest a better way?
Update...
Looking at it another way shoIndex
is assigned as a NSNumber
that sometimes contains a NSString
value @"<null>"
. Does Obj-C have something like an isa
operator that I could use to check the type of the contents of shoIndex
?
TIA, Pedro.
回答1:
Use [shoObject class]
to get the class of an object; so, to test shoObject
's class, you would use
[shoObject isKindOfClass:[NSString class]];
Once you've sorted out what markers define an empty string or NSNumber, you can create a macro. I do with this by keeping an IsEmpty macro in a file called CommonMacros.h. Here's the code:
//Thanks Wil
//http://wilshipley.com/blog/2005/10/pimp-my-code-interlude-free-code.html
static inline BOOL IsEmpty(id thing) {
return thing == nil
|| ([thing isEqual:[NSNull null]]) //JS addition for coredata
|| ([thing respondsToSelector:@selector(length)]
&& [(NSData *)thing length] == 0)
|| ([thing respondsToSelector:@selector(count)]
&& [(NSArray *)thing count] == 0);
}
Then, after importing CommonMacros.h, you can call the function like this:
if (IsEmpty(shotIndex)) {
//do stuff
}
This should take care of this problem, and will also work on strings, arrays, etc, as you can see from the code. Thanks to Wil Shipley!
回答2:
In some cases, such as missing keys in NSUserDefaults, you get back the literal @"" as an empty string.
Here's my safe check for an NSNumber.
Note the check for it being an NSNumber occurs first because NSNumber doesn't understand isEqualToString
id savedPin = [[NSUserDefaults standardUserDefaults] valueForKey:@"blah"]; // don't assume is created so don't type as NSNumber*
if ( ![savedPin isKindOfClass:[NSNumber class]] && [savedPin isEqualToString:@""]) {
回答3:
In Objective-c, it's nil
not null
. So:
if (shotIndex != nil) {
// its not nil
}
来源:https://stackoverflow.com/questions/4231318/how-to-check-for-null-value-in-nsnumber