在我的应用程序中,我有一个CoreGraphics图像绘制模块。该应用程序在CGContextAddPath()函数调用中随机崩溃。路径是使用CGPathCreateMutable()函数调用创建的CGPathRef对象。示例代码如下:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if (touching) return;

    //start a new path
    path = CGPathCreateMutable();
    //set the path's starting point
    UITouch *touch = (UITouch *)[touches anyObject];
    CGPathMoveToPoint(path, NULL, [touch locationInView:m_view].x, [touch locationInView:m_view].y);

    touching = YES;
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    if (touching){
        //get the current location of the touch event
        UITouch *theTouch = (UITouch *)[touches anyObject];
        pathPoint = [theTouch locationInView:m_view];
        CGPathAddLineToPoint(path, NULL, pathPoint.x, pathPoint.y);
        [canvasLayer setNeedsDisplay];
    }
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    if (!touching) return;

    //create a new image context
    UIGraphicsBeginImageContext(CGSizeMake(backgroundLayer.bounds.size.width,  backgroundLayer.bounds.size.height));

    //grab a reference to the new image context
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    //push the image context to the top of the drawing stack
    UIGraphicsPushContext(ctx);
    //set the blend mode to prevent white pixels from
    //covering up the lines that have already been drawn
    CGContextSetBlendMode(ctx, kCGBlendModeDarken);

    if (cacheImage != nil) {
        //draw the cached state of the image to the image context and release it
        [cacheImage drawInRect:CGRectMake(0, 0, backgroundLayer.bounds.size.width, backgroundLayer.bounds.size.height)];
    }

    //blend the drawing layer into the image context
    [canvasLayer drawInContext:ctx];
    //we're done drawing to the image context
    UIGraphicsPopContext();
    //store the image context so we can add to it again later
    cacheImage = UIGraphicsGetImageFromCurrentImageContext();

    //we're finished with the image context altogether
    UIGraphicsEndImageContext();
    touching = NO;
    //release the path
    CGPathRelease(path);

    //update the background layer (we'll need to draw the cached image to the background)
    [backgroundLayer setNeedsDisplay];
 }

- (void)drawLayer:(CATiledLayer *)layer inContext:(CGContextRef)ctx {
    //this method is handling multiple layers, so first
    //determine which layer we're drawing to
    if (layer == canvasLayer) {
        if (!touching) return;

        //add the path to the context
        CGContextAddPath(ctx, path); /***Exception points to this line***/
        //set a line width and draw the path
        CGContextSetLineWidth(ctx, 6.0f);//---thikness of line
        CGContextStrokePath(ctx);
    }
    else if (layer == backgroundLayer) {
        //remember the current state of the context
        CGContextSaveGState(ctx);
        //the cached image coordinate system is upside down, so do a backflip
        CGContextTranslateCTM(ctx, 0, backgroundLayer.bounds.size.height);
        CGContextScaleCTM(ctx, 1.0, -1.0);
        //draw the image
        CGImageRef ref = cacheImage.CGImage;
        CGContextDrawImage(ctx, backgroundLayer.bounds, ref);
        //restore the context to its pre-flipped state
        CGContextRestoreGState(ctx);
    }
}


从设备获得的诊断崩溃报告显示:

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Subtype: KERN_PROTECTION_FAILURE at 0x090d3330
Triggered by Thread:  13

    Thread 13 name:  Dispatch queue: com.apple.root.default-qos
Thread 13 Crashed:
0   ???                                  0x090d3330 0 + 151860016
1   CoreGraphics                         0x22886b6c 0x22874000 + 76652
2   CoreGraphics                         0x228a036e 0x22874000 + 181102
3   MyApplication                        0x001c8062 0xb6000 + 1122402
4   QuartzCore                           0x256d08fc 0x25695000 + 243964
5   QuartzCore                           0x257a9e86 0x25695000 + 1134214
6   QuartzCore                           0x256fdd14 0x25695000 + 429332
7   libdispatch.dylib                    0x30f99866 0x30f8b000 + 59494
8   libdispatch.dylib                    0x30f9a89e 0x30f8b000 + 63646
9   libsystem_pthread.dylib              0x3110eda6 0x3110e000 + 3494
10  libsystem_pthread.dylib              0x3110eaf8 0x3110e000 + 2808


当我在崩溃报告中符号化内存地址时,异常指向CGContextAddPath(ctx,path);。是否由使用CGPathRelease(path);显式释放路径引起的?如果我注释了释放功能,则应用程序不会崩溃,但是会导致内存泄漏吗?

最佳答案

您可以在touchEnded中破坏路径,但是之后可能会调用drawLayer。

关于ios - iOS 8.3-CoreGraphics图像绘图中的EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29895303/

10-12 02:06