Bridge Cocoa and CoreGraphics Geometry

The Google Video page for the Core Animation talk allows viewers to leave comments. Someone called "twobyte" corrected my note in the talk about needing to build 64-bit in order to use NS and CG geometry types interchangeably. It turns out you just need to define NS_BUILD_32_LIKE_64.

I actually saw this definition listed in NSGeometry.h before, but for some reason passed it off as an internal testing tool. It turns out this is incredibly easy and incredibly useful. Here's twobyte's comment:

Scott made a wrong comment that CG geometry primitives (like CGPoint, CGRect, and CGSize) differ from their NS counterparts unless you compile for 64-bit. In fact, they are identical in 32-bit compile as long as you use NS_BUILD_32_LIKE_64 in build settings.

And I'm happy to say it's true. This substantially simplifies programming with Core Animation because you don't have to use conversion functions like NSRectToCGRect() or NSSizeToCGSize(). The only qualifier seems to be that you must be targeting Leopard specifically for this to work.

To use this, just double-click on a target in Xcode, click the Build tab, and search for "preprocessor" in the search field. Double-click the Preprocessor Macros item to bring up the list, click the plus button to add a new entry, and paste in NS_BUILD_32_LIKE_64. Done.

Xcode Settings 1

Xcode Settings 2

Now just clean and rebuild and you can use NSPoint/CGPoint, NSSize/CGSize, and NSRect/CGRect — all interchangeably. How great is that? For some reason I couldn't get this to work as a project-wide build setting, so just set it on the target itself, if necessary.

Thanks again to twobyte.
Design Element
Bridge Cocoa and CoreGraphics Geometry
Posted Feb 14, 2008 — 6 comments below


Tony Arnold — Feb 14, 08 5486

Oh dear lordy, thankyou :) You've just saved me lines and lines of rect conversions! Awesome!

Keith Duncan — Feb 14, 08 5487

As a caveat this will also change the definitions of NSInteger and NSUInteger to long and unsigned long respectively. Despite the return types/address being 64 Bit quantities the underlying 32 bit API won't return values/address' above the 4GB ceiling.

Note: this doesn't alter the definition of the CGFloat type, it is exclusively float/double depending on the architecture.

Jens Alfke — Feb 14, 08 5490

That is good to know!

A more straightforward way to enable this is just to edit your target's prefix file ("TargetName.pch") and add

#define NS_BUILD_32_LIKE_64

at the top (above the first #import.)

Jean-Daniel Dupas — Feb 15, 08 5494

Despite the return types/address being 64 Bit quantities the underlying 32 bit API won't return values/address' above the 4GB ceiling.

long are 32 bits on 32 bits plateform, so changing NSInteger from int to long will not change the "in memory" representation, but only the method signature.

I don't think this will generate binary incompatible code, but it may break some mechanisms that rely on method signature (like invocation).

Eric Wing — Feb 15, 08 5496

This will also cause problems if you rely on 3rd-party built libraries using C++ /Obj-C++ and they didn't define this. Even though the sizeof(long) == sizeof(int) == 4-bytes in 32-bit, C++ namemangling and stricter typing prevents linking.

This became a big issue for us with OpenSceneGraph (documented here) because Apple changed the definitiion of GLenum from long to int under 32-bit in Leopard. They didn't realize the ramifications of this for C++ library writers and I caught the mistake too late for them (right after WWDC) to them to change back.

We have just started shipping our own OSG cross-compile SDKs for 10.4 and 10.5 to help users deal with this problem, but it is kind of unfortunate we have to do this for something as unspectacular as this. (If there were new Leopard-only features we used, then maybe it would be easier to accept/justify.)

Keith Duncan — Feb 22, 08 5541

@Jean-Daniel Dupas

You're right, longs are 32 bit in ILP32. Don't how I decided that they were 64 bit.

But my point on CGFloat is still valid :p


Comments Temporarily Disabled

I had to temporarily disable comments due to spam. I'll re-enable them soon.

Copyright © Scott Stevenson 2004-2015