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.
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.
Bridge Cocoa and CoreGraphics Geometry
Posted Feb 14, 2008 — 6 comments below
Posted Feb 14, 2008 — 6 comments below
Tony Arnold — Feb 14, 08 5486
Keith Duncan — Feb 14, 08 5487
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
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
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 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
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