问题
I am working CGlayers for drawing. I have implemented the drawing part, the drawingView(canvas) where the user will draw is dynamic, what I mean by this is, user can increase/decrease height of the drawingView(Canvas)
For example by default size - 500*200
When user clicks on expand button - 500*300
So here is my function when user expands the canvas,
- (void)IncreaseCanavasSize
{
CGContextRef layerContext1 = CGLayerGetContext(permanentDrawingLayer );
CGContextDrawLayerInRect(layerContext1, rectSize, newDrawingLayer);
rectSize = self.bounds;
CGFloat scale = self.contentScaleFactor;
CGRect bounds = CGRectMake(0, 0, self.bounds.size.width * scale, self.bounds.size.height * scale);
CGLayerRef layer = CGLayerCreateWithContext(layerContext1, bounds.size, NULL);
CGContextRef layerContext = CGLayerGetContext(layer);
CGContextScaleCTM(layerContext, scale, scale);
[self setNewDrawingLayer:layer];
CGLayerRelease(layer);
CGContextDrawLayerInRect(layerContext, self.bounds, permanentDrawingLayer);
permanentDrawingLayer = nil;
}
So let me explain what I am doing in the above code, I am creating a newLayer with size before it is increased, and then transfer the previousDrawing from "*permanentDrawingLayer" to this "newDrawingLayer" and making "permanentDrawing" nil*
So Whenever I draw, I draw into permanentDrawingLayer, here is my drawRect method
- (void)drawRect:(CGRect)rect
{
if(permanentDrawingLayer == nil)
{
CGFloat scale = self.contentScaleFactor;
CGRect bounds = CGRectMake(0, 0, self.bounds.size.width * scale, self.bounds.size.height * scale);
CGLayerRef layer = CGLayerCreateWithContext(context, bounds.size, NULL);
CGContextRef layerContext = CGLayerGetContext(layer);
CGContextScaleCTM(layerContext, scale, scale);
[self setPermanentDrawingLayer:layer];
CGLayerRelease(layer);
}
CGContextRef layerContext = CGLayerGetContext(permanentDrawingLayer);
CGContextBeginPath(layerContext);
CGContextAddPath(layerContext, mutablePath);
CGContextSetLineWidth(layerContext, self.lineWidth);
CGContextSetLineCap(layerContext, kCGLineCapRound);
CGContextSetLineJoin(layerContext, kCGLineJoinRound);
CGContextSetAllowsAntialiasing(layerContext, YES);
CGContextSetShouldAntialias(layerContext, YES);
CGContextSetStrokeColorWithColor(layerContext, self.lineColor.CGColor);
CGContextSetFillColorWithColor(layerContext, self.lineColor.CGColor);
CGContextSetBlendMode(layerContext,kCGBlendModeNormal);
CGContextStrokePath(layerContext);
CGContextDrawLayerInRect(context,rectSize, newDrawingLayer);
CGContextDrawLayerInRect(context, self.bounds, permanentDrawingLayer);
}
Here you can see, I draw newDrawingLayer with rectSize, and permanetDrawingLayer with newSize, So whenever, I draw on a canvas, if user has increased the size, the newDrawingLayer will draw that, and new drawing whatever user does will be done in permanentDrawingLayer. Hope it is clear.
Now here are my problems
1) Memory spikes to 10MB, when I drawSomething and increase the canvasSize, so if I do this action always you can imagine, how fast my app will terminate due to memory pressure.
2) What I saw was if I comment the Line " permanentDrawingLayer = nil" in function - "IncreaseCanavasSize", then memory doesnt spikes up, but if I dont do that, then when I draw next time, then Layer with newSize will not be created and I will get duplicate drawings.
So I need all your help
回答1:
Your permanentDrawingLayer
is a CGLayerRef
so setting it to NULL, don't release it.
You need to call CGLayerRelease(permanentDrawingLayer)
before setting it to NULL.
- (void)IncreaseCanavasSize
{
CGContextRef layerContext1 = CGLayerGetContext(permanentDrawingLayer );
CGContextDrawLayerInRect(layerContext1, rectSize, newDrawingLayer);
rectSize = self.bounds;
CGFloat scale = self.contentScaleFactor;
CGRect bounds = CGRectMake(0, 0, self.bounds.size.width * scale, self.bounds.size.height * scale);
CGLayerRef layer = CGLayerCreateWithContext(layerContext1, bounds.size, NULL);
CGContextRef layerContext = CGLayerGetContext(layer);
CGContextScaleCTM(layerContext, scale, scale);
[self setNewDrawingLayer:layer];
CGLayerRelease(layer);
CGContextDrawLayerInRect(layerContext, self.bounds, permanentDrawingLayer);
CGLayerRelease(permanentDrawingLayer);
permanentDrawingLayer = NULL;
}
Also if your method -setPermanentDrawingLayer:
looks like the method -setCurrentDrawingLayer:
in your previous question.
In -IncreaseCanavasSize
You can simply replace the line permanentDrawingLayer = nil;
with [self setPermanentDrawingLayer:NULL];
, then it will release the CGLayerRef and set it to NULL.
来源:https://stackoverflow.com/questions/22500008/memory-issues-with-cglayer