How do you encode and decode a CGPoint struct using NSCoder?
+5
A:
CGPoint
s and NSPoint
s 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
2009-01-15 19:51:30
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
2009-01-15 20:55:39
Furthermore, Foundation provides two inline functions named NSPoint{To,From}CGPoint. No need for pointer casting or a union.
Peter Hosey
2009-01-16 02:30:06
+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
2009-01-15 23:23:16
+1 This seems like a much better, less hackish general-purpose solution.
Quinn Taylor
2010-03-08 22:50:27