为什么在释放先前创建的CGMutablePathRef时会得到SIGABRT?

问题描述:

在我的UIView中,我有几个CGPath存储在一个NSArray(availablePaths)中。为什么在释放先前创建的CGMutablePathRef时会得到SIGABRT?

之前绘制任何东西,我创建一个缩放版本的每个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)绘制工作正常, 但当然,我得到了内存泄漏。

尝试找到的解决方案here添加CGPathRef s到NSMutableArray:包装CGPathRef里面UIBezierPath

编辑:看起来你可以使用-[UIBezierPath applyTransform:]来避免CGPathRefscaleAllPaths:

- (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); 
    } 
    ... 
} 
+0

+1无需创建另一个CGMutablePathRef。不过,我想知道,我在这里实际做错了什么。我假设'replaceObjectAtIndex:withObject'释放前一个对象并保留新对象,对吗? – roplacebo 2013-03-16 11:48:29

发现,我被释放CGPath对象在另一个类中,我把它发给:

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

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

谢谢,R。

+0

这很有道理,很高兴你明白了。它看起来很奇怪,因为它是失败的,因为像以前一样将任何'CFPathRef'强制转换为'id'。 – 2013-03-16 14:36:53