1

在下面的代码中执行“CGContextFillRect”语句后,我看到内存使用量急剧增加(在 iPad 上从 39 MB 增加到 186 MB)。这里有什么问题吗。

我的应用程序最终崩溃了。

PS:令人惊讶的是,内存峰值出现在第 3 代和第 4 代 iPad 上,而不是在第 2 代 iPad 上。

    - (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setBackgroundColor:[UIColor clearColor]];
    }
    return self;
}


- (id)initWithFrame:(CGRect)iFrame andHollowCircles:(NSArray *)iCircles {

    self = [super initWithFrame:iFrame];
    if (self) {
        [self setBackgroundColor:[UIColor clearColor]];
        self.circleViews = iCircles;
    }
    return self;
}


- (void)drawHollowPoint:(CGPoint)iHollowPoint withRadius:(NSNumber *)iRadius {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(currentContext, self.circleRadius.floatValue);
    [[UIColor whiteColor] setFill];
    CGContextAddArc(currentContext, iHollowPoint.x, iHollowPoint.y, iRadius.floatValue, 0, M_PI * 2, YES);
    CGContextFillPath(currentContext);
}


- (void)drawRect:(CGRect)rect {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGContextSaveGState(currentContext);
    CGRect aRect = [self.superview bounds];
    [[UIColor whiteColor]setFill];
    CGContextFillRect(currentContext, aRect);

    CGContextSaveGState(currentContext);
    [[UIColor blackColor]setFill];
    CGContextFillRect(currentContext, aRect);
    CGContextRestoreGState(currentContext);

    for (MyCircleView *circleView in self.circleViews) {
        [self drawHollowPoint:circleView.center withRadius:circleView.circleRadius];
    }

    CGContextTranslateCTM(currentContext, 0, self.bounds.size.height);
    CGContextScaleCTM(currentContext, 1.0, -1.0);
    CGContextSaveGState(currentContext);
}
4

1 回答 1

1

这段代码不太有意义;我假设你已经删除了它的一部分?您创建一个空白 Alpha 蒙版,然后将其丢弃。

如果上面的代码真的是你在做的,你真的不需要画任何东西。您可以创建一个 12MB 的内存区域并用重复的 1 0 0 0(ARGB 中的不透明黑色)填充它,然后创建一个图像。但我认为你实际上做的不止这些。

可能您已将此视图配置为contentScaleFactor设置为匹配scalefrom UIScreen,并且此视图非常大。第 3 代和第 4 代 iPad 具有 Retina 显示屏,因此比例为 2,绘制视图所需的内存是 4 倍。

也就是说,您应该只期望大约 12MB 来容纳全屏图像 (2048*1536*4)。您看到 10 倍的事实表明正在发生更多事情,但我怀疑它仍然可能与绘制过多副本有关。

如果可能,您可以将比例降低到 1,以使视网膜和非视网膜的行为相同。


编辑:

您编辑的代码与原始代码非常不同。没有尝试在此代码中制作图像。我已经尽我所能对其进行了测试,我没有看到任何令人惊讶的内存峰值。但是有几个奇怪的地方:

  • 您没有正确平衡CGContextSaveGState. CGContextRestoreGState这实际上可能会导致内存问题。
  • 为什么你把矩形全部画成白色,然后全部画成黑色?
  • 你的 rect 是[self.superview bounds]. 那是在错误的坐标空间中。您几乎可以肯定的意思是[self bounds].
  • 为什么在返回之前翻转上下文drawRect然后保存上下文?这根本没有意义。

我会假设你drawRect:会是这样的:

- (void)drawRect:(CGRect)rect {
  [[UIColor blackColor] setFill];
  UIRectFill(rect); // You're only responsible for drawing the area given in `rect`

  for (CircleView *circleView in self.circleViews) {
    [self drawHollowPoint:circleView.center withRadius:circleView.circleRadius];
  }
}
于 2013-10-11T20:53:12.770 回答