Tuesday, March 15, 2011

Encoding CGPoint struct with NSCoder

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

From stackoverflow
  • 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];
    
    Ahruman : 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.
    Peter Hosey : Furthermore, Foundation provides two inline functions named NSPoint{To,From}CGPoint. No need for pointer casting or a union.
  • 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];
    
    Quinn Taylor : +1 This seems like a much better, less hackish general-purpose solution.

0 comments:

Post a Comment