Memory issues with CGlayer

怎甘沉沦 提交于 2019-12-11 05:29:09

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!