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.
But in Objective-C, invoking a method on nil returns a zero value — which is to say, “ nil begets nil “. This fact alone significantly simplifies things for Objective-C developers, as it obviates the need to check for nil before doing anything: // For example, this expression... if (name !=
NSNumber is a subclass of NSValue that offers a value as any C scalar (numeric) type. It defines a set of methods specifically for setting and accessing the value as a signed or unsigned char , short int , int , long int , long long int , float , or double or as a BOOL .
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With