0

Under ARC, is it possible to encode/decode a CGMutablePathRef (or its non-mutable form) using NSCoding? Naively I try:

path = CGPathCreateMutable();
...
[aCoder encodeObject:path]

but I get a friendly error from the compiler:

Automatic Reference Counting Issue: Implicit conversion of an Objective-C pointer to 'CGMutablePathRef' (aka 'struct CGPath *') is disallowed with ARC

What can I do to encode this?

tacos_tacos_tacos
  • 10,277
  • 11
  • 73
  • 126
  • possible duplicate of [CGPathRef encoding](http://stackoverflow.com/questions/1429426/cgpathref-encoding) – yuji Mar 30 '12 at 08:08

3 Answers3

1

Your problem is not due to ARC, but to the mismatch between Core Graphics code based in C and the NSCoding mechanism based in Objective-C.

To use encoders/decoders, you need to use objects that conform to the Objective-C NSCoding protocol. CGMutablePathRef does not conform since it is not an Objective-C object but a Core Graphics object reference.

However, UIBezierPath is an Objective-C wrapper for a CGPath and it does conform.

You can do the following:

CGMutablePathRef mutablePath = CGPathCreateMutable();
// ... you own mutablePath. mutate it here...
CGPathRef persistentPath = CGPathCreateCopy(mutablePath);
UIBezierPath * bezierPath = [UIBezierPath bezierPathWithCGPath:persistentPath];
CGPathRelease(persistentPath);
[aCoder encodeObject:bezierPath];

and then to decode:

UIBezierPath * bezierPath = [aCoder decodeObject];
if (!bezierPath) { 
  // workaround an issue, where empty paths decode as nil
  bezierPath = [UIBezierPath bezierPath]; 
}
CGPathRef  path = [bezierPath CGPath];
CGMutablePathRef * mutablePath = CGPathCreateMutableCopy(path);
// ... you own mutablePath. mutate it here 

This works in my tests.

Sunny Shah
  • 12,990
  • 9
  • 50
  • 86
algal
  • 27,584
  • 13
  • 78
  • 80
1

NSCoding is a protocol. Its methods can only be used with objects that conform to the NSCoding protocol. a CGPathRef isn't even an object, so NSCoding methods won't work directly. That's why you're getting that error.

Here's a guy who has come up with a way to serialize CGPaths.

Community
  • 1
  • 1
yuji
  • 16,695
  • 4
  • 63
  • 64
  • I went ahead and changed over to using `UIBezierPath` although I could have wrapped the CGPath using one of the `UIBezierPath` class methods. – tacos_tacos_tacos Mar 30 '12 at 12:21
0

If you asking for storing CGPath persistently you should you use the CGPathApply function. Check here for how to do that.

Vignesh
  • 10,205
  • 2
  • 35
  • 73