tags:

views:

1245

answers:

2

How do you encode and decode a CGPoint struct using NSCoder?

+5  A: 

CGPoints and NSPoints are both structures composed of two CGFloat values, so you can freely pass them around as each other. The quick and dirty way would be:

NSCoder *myNSCoder;
CGPoint myPoint;
[myNSCoder encodePoint:*(NSPoint *)myPoint];

This will usually work, but it technically breaks the C99 strict aliasing rules. If you want to be 100% compatible with the standard, you'll have to do something like:

typedef union
{
  CGPoint cgPoint;
  NSPoint nsPoint;
} CGNSPoint;

CGNSPoint cgnsPoint = { .cgPoint = myPoint };
[myNSCoder encodePoint:cgnsPoint.nsPoint];
Adam Rosenfield
However, if you’re building for the 64-bit runtime, or have NS_BUILD_32_LIKE_64 defined to 1, NSPoint and CGPoint are typedefed to the same struct, so no casting or union shenanigans are required.
Ahruman
Furthermore, Foundation provides two inline functions named NSPoint{To,From}CGPoint. No need for pointer casting or a union.
Peter Hosey
+4  A: 

To encode:

CGPoint point = /* point from somewhere */
NSValue *pointValue = [NSValue value:&point withObjCType:@encode(CGPoint)];
[coder encodeObject:pointValue forKey:@"point"];

To decode:

NSValue *decodedValue = [decoder decodeObjectForKey:@"point"];
CGPoint point;
[decodedValue getValue:&point];
sbooth
+1 This seems like a much better, less hackish general-purpose solution.
Quinn Taylor