NSNumber, CFNumber, and CFBoolean

Interesting fact of the day. NSNumber and CFNumber are toll-free bridged, right?

Not according to Apple. Nowhere on NSNumber’s class page nor in the “Number and Value Programming” guide does it mention that NSNumber and CFNumber are toll-free bridged.

Next question. CFNumber and NSNumber are toll-free bridged, right?

Of course.

Recently I’ve been working on an outline view property list editor for Dockyard, and I think I have a bit of a clue as to what’s going on. Most NSNumber types are instances of NSCFNumber, similar to most of Apple’s bridged classes.

But NSNumbers created with BOOL values are instances of NSCFBoolean. And CFBooleans aren’t CFNumbers.

So NSCFBoolean implements enough of NSNumber’s methods to pass as an NSNumber…and NSNumber subclasses can already pass as CFNumbers. The most definitive toll-free bridging reference, Interchangeable Data Types, does say CFNumber and NSNumber are toll-free bridged. My hypothesis is because all CFNumbers are NSNumbers but not vice versa, some documentation writer decided not to include the usual toll-free bridging footnote.

Even though it should be there. The Property List Programming Guide implies the same thing. Interestingly, while CFBooleans are also valid NSNumbers, not all NSNumbers are valid CFBooleans. Which is why CFBoolean is not “toll-free bridged” with NSNumber, even though it will, in fact, work perfectly well to cast a CFBooleanRef to NSNumber *.

Also interesting is that while CFBooleans are not CFNumbers in the CoreFoundation hierarchy, they can be casted as if they were. Weird, huh?

Lack of bridging info for NSNumber filed as documentation bug #5688009