10

将我的 iPad (mini) 更新到 iOS7 后,我体验到我的绘图应用程序在几次敲击后就会出现延迟和崩溃。

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

该代码基本上将路径写入图像上下文,或多或少像这样:

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,同时只有一两个“活动”。绘图流畅快速,没有记忆警告,也没有减速。

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

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

4

2 回答 2

11

我把我的绘图代码放在一个自动释放池中。这解决了我的问题。

例如:-

@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();
}
于 2013-12-02T06:31:06.020 回答
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();
}

在 touchesMoved 上,我调用了一个 drawLine 方法,该方法进行了一些曲线插值、画笔大小调整和结束线逐渐变细,然后执行 [self setNeedsDisplay];

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

于 2013-11-04T15:47:48.357 回答