Skip to content

Instantly share code, notes, and snippets.

@brentsimmons
Created July 28, 2012 19:06
Show Gist options
  • Save brentsimmons/3194441 to your computer and use it in GitHub Desktop.
Save brentsimmons/3194441 to your computer and use it in GitHub Desktop.
Checking if an object is empty
BOOL RSIsEmpty(id obj) {
return obj == nil || obj == [NSNull null] || ([obj respondsToSelector:@selector(length)] && [(NSData *)obj length] == 0) || ([obj respondsToSelector:@selector(count)] && [obj count] == 0);
}
BOOL RSStringIsEmpty(NSString *s) {
/*22 Feb. 2011: added NSNull check. JSON parser can put a null where we expect a string, and NSNull throws an exception when checking length. Since [NSNull null] is, arguably, emptiness, it makes sense to include it.*/
return s == nil || (id)s == (id)[NSNull null] || [s length] == 0;
}
@fjolnir
Copy link

fjolnir commented Jul 29, 2012

Wouldn't adding -length { return 0; } to NSNull serve the same purpose without the need for a clumsy function?

@brentsimmons
Copy link
Author

I worry about the safety of adding a category method to NSNull. I don't know how it's used internally in Foundation and Cocoa -- if there is some code somewhere that does a respondsToSelector with length, and then makes incorrect assumptions based on a YES return, there could be bad consequences. (This seems possible just because length is such a commonly-used selector.) (And, as a rule I always prefix my category methods. Healthy paranoia.)

Also, I like to apply Occam's Razor (don't add unnecessary entities) to code . Adding a category method adds an additional entity that isn't needed.

The function looks clumsy, for sure -- and that's kind of the point. That clumsiness exists in just one place in my project instead of multiplied all over the place.

@fjolnir
Copy link

fjolnir commented Jul 30, 2012

Alright, I see your point (although I'm not sure how Occam's razor applies; I found adding a method to the class missing it to be the simpler of the two options :)

@implementation NSObject (utils)
- (BOOL)bs_notEmpty { return NO; }
@end
@implementation NSArray (utils)
- (BOOL)bs_notEmpty { return [self count] > 0; }
@end
@implementation NSString (utils)
- (BOOL)bs_notEmpty { return [self length] > 0; }
@end

@brentsimmons
Copy link
Author

You've got three methods there instead of one function (and one optional function). And you'd need more to cover NSDictionary, NSSet, etc.

I'd also add: I have a bias against creating category methods. I create them sometimes, sure, I don't want to create my own personal dialect of Cocoa. I find it more lightweight to just have a couple functions.

@fjolnir
Copy link

fjolnir commented Jul 30, 2012

We just seem to have opposite biases.
Rather than having a function that tests for every possibility I like the approach of having multiple message responses, each performing only the exact amount of work required. I'm not however, saying that one or the other is invalid.

@brentsimmons
Copy link
Author

In general I agree with you completely -- the object-oriented approach is best. But I will consider that there are occasional special cases, and I think this is one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment