Get It Down

taking notes cause i'll forget

Comparing to NSNull

Checks to NSNull come up a lot when dealing with things like parsing JSON and while it’s mostly just ==, there are some options.

The officially sanctioned method is NSNull sample code, but this will generate a warning in clang (BOOO HISSSS).

So here are the options as I see them:

- (void)someMethod
{
    NSString *aString = @"loremipsum";
    
    // This will complain: "Comparison of distinct pointer types ('NSString *' and 'NSNull *')"
    if (aString != [NSNull null])
    {
        
    }
    
    // This works (at least for strings), but isEqual: does different things 
    // for different classes, so it's not ideal
    if ([aString isEqual:[NSNull null]]) 
    {
        
    }
    
    // If you cast it to the class you're comparing against
    // then you're good to go
    if (aString != (NSString *)[NSNull null])
    {
        
    }
    
    // But we can also just cast it to id and
    // that works generically
    if (aString != (id)[NSNull null])
    {
        
    }
    
    // The thing that would be really cool,
    // would be [NSNull null] returning
    // id (like in the sample category below).
    // Wouldn't count on that one though.
    if (aString != [NSNull idNull])
    {
        
    }
}
@interface NSNull (idNull)
+ (id)idNull;
@end
@implementation NSNull (idNull)
+ (id)idNull { return [NSNull null]; }
@end

Casting to (id) seems like the simplest way to handle this one, so that’s the one I’m using right now.

Update:

One of my coworkers, @pgor, pointed out that he uses NSNull’s isEqual, which seems like a sensible enough thing to do. (I’m guessing Apple isn’t going to toss anything to screwy into an isEqual on an object that’s basically single purpose.)

if ([[NSNull null] isEqual:aString]) 
{
        
}

Also forgot to mention in the original post: it’s worth filing a bug against the documentation on NSNull to see what Apple’s official position is in this post static humiliator world we inhabit.

Radar

XXX Timestamps

It’s pretty common to see a timestamp like this

2001-07-04T12:08:56-07:00

supplied by xml and json feeds.

I’m pretty sure this is because one of the relatively common date formats supported by Java is

yyyy-MM-dd’T’HH:mm:ssXXX

and as we all know, Java and the internet are besties.

Thing is, NSDateFormatter doesn’t know what to do with XXX time zone formats, because it’s based on unicode date formatting and XXX is ISO 8601.

Yay for standards!

Lucky for us we know two things worth knowing

  • there aren’t half time zones
  • time format string can escape segments with single quotes

so our date format string for our formatter becomes

yyyy-MM-dd’T’HH:mm:ssZZ’:00’

and we’re off to the races.

Everybody’s happy. Except possibly all those people writing Java.

(Insert your own joke about porn in the app store and XXX time, or maybe something about how our evil Cupertino overlords are censoring our time formatters!)

Github With Two+ Accounts

Managing github with two accounts is not obvious. You’re connecting to the same host, but sometimes you want to use one identity and somethings the other.

This is a balancing act of git configuration and ssh configuration, but it’s not as bad as it might seem, once you’re set up.

Making NSAssert Play Nice With Blocks

NSAssert is actually a macro that calls NSAssertionHandler using the handleFailureInMethod:object:file:lineNumber:description method with self as the argument for object. This is fine and dandy for most asserts, but if you’re in a block, you probably just made a retain cycle.

Luckily this is pretty easy to fix by logging the function instead of the object:

#if !defined(NS_BLOCK_ASSERTIONS)

#define BlockAssert(condition, desc, ...) \
do {\
if (!(condition)) { \
[[NSAssertionHandler currentHandler] handleFailureInFunction:NSStringFromSelector(_cmd) \
file:[NSString stringWithUTF8String:__FILE__] \
lineNumber:__LINE__ \
description:(desc), ##__VA_ARGS__]; \
}\
} while(0);

#else // NS_BLOCK_ASSERTIONS defined

#define BlockAssert(condition, desc, ...) 

#endif

This new macro behaves the same and will compile out with the same flags as NSAssert.

Easy, Peasy.