我在下面的代码中看到“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);
}
答案 0 :(得分:1)
这段代码没有多大意义;我假设你已经删除了它的一部分?您创建一个空白的alpha蒙版,然后将其丢弃。
如果上面的代码真的是你正在做的,你真的不需要绘制任何东西。您可以创建一个12MB的内存区域并用重复的1 0 0 0(ARGB中的不透明黑色)填充它,然后创建一个图像。但我认为你实际上做的不仅仅是那个。
可能您将此视图配置为contentScaleFactor
设置为与scale
中的UIScreen
匹配,此视图非常大。第3代和第4代iPad都有Retina显示屏,因此比例为2,绘制视图所需的内存是4倍。
那就是说,你应该只想要大约12MB来保持全屏图像(2048 * 1536 * 4)。事实上,你看到10x表明会发生更多事情,但我怀疑它仍然与绘制太多副本有关。
如果可能,您可以将比例降低到1,使视网膜和非视网膜的行为相同。
编辑:
您编辑的代码与原始代码非常不同。没有尝试在此代码中制作图像。我尽我所能地测试了它,并且我没有看到任何令人惊讶的记忆峰值。但有几个奇怪之处:</ p>
CGContextSaveGState
与CGContextRestoreGState
。这实际上可能会导致内存问题。[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];
}
}