2

I want to add NSCoding support to an c array of structs. Specifically this is for a subclass of MKPolyline, i.e. this is what I have to work with:

@property (nonatomic, readonly) MKMapPoint *points;
@property (nonatomic, readonly) NSUInteger pointCount;

+ (MKPolyline *)polylineWithPoints:(MKMapPoint *)points count:(NSUInteger)count;

I found a good answer on how to encode a individual struct. E.g.

NSValue* point = [NSValue value:&aPoint withObjCType:@encode(MKMapPoint)];
[aCoder encodeObject:point forKey:@"point"];

.... 

NSValue* point = [aDecoder decodeObjectForKey:@"point"];
[endCoordinateValue getValue:&aPoint];

Is there a nice way to apply this to a c Array - or will I simply have to iterate over the c-array?

Community
  • 1
  • 1
Robert
  • 37,670
  • 37
  • 171
  • 213
  • How about `[NSValue value:aPointArray withObjCType:@encode(MKMapPoint[12])]` or similar? –  Feb 16 '13 at 18:49
  • @H2CO3 This method may be deprecated in a future release. You should use `valueWithBytes:objCType:` instead. – voromax Feb 16 '13 at 18:54
  • @voromax Didn't check the docs, just repeated what OP had, but true. –  Feb 16 '13 at 18:56

1 Answers1

4

Note: This approach only works if the data isn't going between processors with different "endian-ness". It should be safe going from iOS to iOS, certainly if only used on a given device.

You should be able to load the memory for the C-array into an NSData object then encode the NSData object.

MKMapPoint *points = self.points;
NSData *pointData = [NSData dataWithBytes:points length:self.pointCount * sizeof(MKMapPoint)];
[aCoder encodeObject:pointData forKey:@"points"];

Update: to get the data back:

NSData *pointData = [aCode decodeObjectForKey:@"points"];
MKMapPoint *points = malloc(pointData.length);
memcpy([pointData bytes], points);
self.points = points;
Robert
  • 37,670
  • 37
  • 171
  • 213
rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • And this will nicely break portability (memdumping `float`s, ehh...) –  Feb 16 '13 at 18:52
  • Yes, if Apple starts using non-ARM chips there may be an issue going between big-endian and little-endian devices. – rmaddy Feb 16 '13 at 18:56
  • Should this portability issues be a concern, or is it unlikely to cause impact? Also how would you convert it back from `NSData` to a `MKMapPoint` array? – Robert Feb 16 '13 at 18:59
  • Im a little stuck again.... I made a new question. http://stackoverflow.com/q/14914265/296446 – Robert Feb 16 '13 at 19:32
  • This wasn't working for me for some reason and it also gave me a warning about sending const void* to void* parameter. I fixed it by using the following: [pointData getBytes:& points length:pointsSize]; – davvilla May 23 '14 at 01:40