简体   繁体   中英

Why do I get a SIGABRT when releasing a previously created CGMutablePathRef?

In my UIView, I have a couple of CGPath's stored in a NSArray (availablePaths).

Before anything is drawn, I create a scaled version of each CGPath and replace the old one in the array.

I get a SIGABRT in drawRect using the following code.

- (void) scaleAllPaths: (CGFloat) scaleFactor
{

 CGAffineTransform transform = CGAffineTransformMakeScale(scaleFactor, scaleFactor);
 CFIndex i;
 for(i=0;i<[availablePaths count];i++){
    id obj = [availablePaths objectAtIndex:i];
    CGPathRef oldPath = (CGPathRef)obj;
    CGMutablePathRef newPath = CGPathCreateMutable();
    CGPathAddPath(newPath, &transform, oldPath);
    [availablePaths replaceObjectAtIndex:i withObject:(id) newPath];
    CGPathRelease(newPath); // <--- causes SIGABRT in drawRect:
 }
}
-(void)drawRect:(CGRect)rect
{
...
 for (int i = 0; i < currentPathIndex; i++) {
      id obj = [availablePaths objectAtIndex:i];
      CGPathRef path = (CGPathRef)obj;
      CGContextBeginPath(context);
      CGContextAddPath(context, path);    // <---  SIGABRT
      CGContextDrawPath(context, kCGPathEOFill);

 }
...

Without the CGPathRelease(newPath) drawing works fine, but of course, I'm getting the memory leak.

Try the solution found here for adding CGPathRef s to NSMutableArray : wrap CGPathRef inside UIBezierPath .

Edit: Looks like you can use -[UIBezierPath applyTransform:] to avoid CGPathRef in scaleAllPaths: .

- (void) scaleAllPaths: (CGFloat) scaleFactor
{
  CGAffineTransform transform = CGAffineTransformMakeScale(scaleFactor,scaleFactor);
  for (UIBezierPath *bezierPath in availablePaths){
    [bezierPath applyTransform:transform];
  }
}

- (void)drawRect:(CGRect)rect
{
  ...
  for (int i = 0; i < currentPathIndex; i++) {
    UIBezierPath *bezierPath = [availablePaths objectAtIndex:i];
    CGPathRef path = bezierPath.CGPath;
    CGContextBeginPath(context);
    CGContextAddPath(context, path);
    CGContextDrawPath(context, kCGPathEOFill);
  }
  ...
}

Found out, I was releasing the CGPath object in another class, I sent it to:

-(void) setPath: (CGPathRef) pathToSet forceClosed: (BOOL) fClosed
{

  if(_path){
    CGPathRelease(_path);
  }
  _path = pathToSet;
  CGPathRetain(_path);  // <--- was missing
}

Thanks,R.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM