CoreGraphics绘图会在iOS 7上导致内存警告/崩溃

时间:2013-10-03 19:33:58

标签: ipad uiimage core-graphics ios7

将我的iPad(mini)更新到iOS7后,我发现我的绘图应用程序在几次中风后滞后并崩溃。

现在,当我使用xcode 5中的Instruments /内存分配工具运行应用程序时,我发现在屏幕上绘图时, VM:CG栅格数据类别正在迅速填满。似乎有大量的 CGDataProviderCreateWithCopyOfData 调用,每个调用大小为3.00Mb。在连续绘制后,应用程序会收到内存警告,并且通常会终止。

代码基本上将路径划分为imagecontext,或多或少像这样:

UIGraphicsBeginImageContext(self.view.frame.size);
[drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

在iOS7 / iPad上,这是非常滞后的并且存在内存问题,而在iOS6上,这是相当快速的并且没有负面的内存占用。

当我在非视网膜iPhone版本中运行此代码时, CGDataProviderCreateWithCopyOfData 调用的大小为604Kb,并且只有一个或两个同时处于“活动”状态。绘图流畅而快速,没有内存警告且没有减速。

关于CoreGraphics和imagecontexts,从iOS6到iOS7发生了什么?

对于任何语言错误或其他可能的愚蠢错误,我们深表歉意。还是一个菜鸟,在我的业余时间做iOS开发。

2 个答案:

答案 0 :(得分:11)

我把我的绘图代码放在autoreleasepool中。这解决了我的问题。

例如: -

@autoreleasepool {
    UIGraphicsBeginImageContext(self.view.frame.size);

    [drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];

    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 5.0);
    CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 1.0, 0.0, 0.0, 1.0);
    CGContextBeginPath(UIGraphicsGetCurrentContext());
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
    CGContextStrokePath(UIGraphicsGetCurrentContext());

    drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}

答案 1 :(得分:3)

我的解决方案一般是创建一个Canvas UIView类来处理所有绘图操作。我写了一个缓存的CGImageRef,然后将缓存与UIImage结合起来:

我的自定义drawRect方法是这样的:

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    UIGraphicsBeginImageContext(CGSizeMake(1024, 768));
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGImageRef cacheImage = CGBitmapContextCreateImage(cacheContext);
    CGContextDrawImage(context, self.bounds, cacheImage);

    // Combine cache with image
    drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
    CGImageRelease(cacheImage);
    UIGraphicsEndImageContext();
}

on touchesMoved我调用drawLine方法做一些曲线插值,画笔大小调整和结束线渐减,然后做一个[self setNeedsDisplay];

这似乎在iOS7中运行良好。对不起,如果我不能更具体,但我不想从我的应用程序发布实际的生产代码:)