为什么在发布以前创建的CGMutablePathRef时会获得SIGABRT?

时间:2013-03-15 13:46:10

标签: ios uiview memory-leaks

在我的UIView中,我有一些CGPath存储在NSArray(availablePaths)中。

绘制任何内容之前,我创建了每个CGPath的缩放版本 并替换数组中的旧旧。

我使用以下代码在drawRect中获得SIGABRT。

- (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);

 }
...

没有CGPathRelease(newPath)绘图工作正常, 但当然,我得到了内存泄漏。

2 个答案:

答案 0 :(得分:1)

尝试使用here找到的解决方案将CGPathRef添加到NSMutableArray:在CGPathRef内包裹UIBezierPath

修改:您似乎可以使用-[UIBezierPath applyTransform:]来避免CGPathRef中的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);
  }
  ...
}

答案 1 :(得分:1)

发现,我在另一个类中释放了CGPath对象,我把它发送到:

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

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

感谢,R。