存储在'imageCrop'中的对象的潜在泄漏

问题描述:

此代码运行良好,但分析时显示潜在的内存泄漏。看起来imageCrop有潜在的内存泄漏。非常感谢您的帮助。存储在'imageCrop'中的对象的潜在泄漏

这是我的代码。

-(CATransformLayer *)transformLayerFromImage:(UIImage *)image Frame:(CGRect)frame Duration:(CGFloat)duration AnchorPiont:(CGPoint)anchorPoint StartAngle:(double)start EndAngle:(double)end 
{ 
    CATransformLayer *jointLayer = [CATransformLayer layer]; 
    jointLayer.anchorPoint = anchorPoint; 
    CALayer *imageLayer = [CALayer layer]; 
    CAGradientLayer *shadowLayer = [CAGradientLayer layer]; 
    double shadowAniOpacity; 

    if (anchorPoint.y == 0.5) { 
     CGFloat layerWidth; 
     if (anchorPoint.x == 0) //from left to right 
     { 
      layerWidth = image.size.width - frame.origin.x; 
      jointLayer.frame = CGRectMake(0, 0, layerWidth, frame.size.height); 
      if (frame.origin.x) { 
       jointLayer.position = CGPointMake(frame.size.width, frame.size.height/2); 
      } 
      else { 
       jointLayer.position = CGPointMake(0, frame.size.height/2); 
      } 
     } 
     else { //from right to left 
      layerWidth = frame.origin.x + frame.size.width; 
      jointLayer.frame = CGRectMake(0, 0, layerWidth, frame.size.height); 
      jointLayer.position = CGPointMake(layerWidth, frame.size.height/2); 
     } 

     //map image onto transform layer 
     imageLayer.frame = CGRectMake(0, 0, frame.size.width, frame.size.height); 
     imageLayer.anchorPoint = anchorPoint; 
     imageLayer.position = CGPointMake(layerWidth*anchorPoint.x, frame.size.height/2); 
     [jointLayer addSublayer:imageLayer]; 
     CGImageRef imageCrop = CGImageCreateWithImageInRect(image.CGImage, frame); 
     imageLayer.contents = (__bridge id)imageCrop; 
     imageLayer.backgroundColor = [UIColor clearColor].CGColor; 

     //add shadow 
     NSInteger index = frame.origin.x/frame.size.width; 
     shadowLayer.frame = imageLayer.bounds; 
     shadowLayer.backgroundColor = [UIColor darkGrayColor].CGColor; 
     shadowLayer.opacity = 0.0; 
     shadowLayer.colors = [NSArray arrayWithObjects:(id)[UIColor blackColor].CGColor, (id)[UIColor clearColor].CGColor, nil]; 
     if (index%2) { 
      shadowLayer.startPoint = CGPointMake(0, 0.5); 
      shadowLayer.endPoint = CGPointMake(1, 0.5); 
      shadowAniOpacity = (anchorPoint.x)?0.24:0.32; 
     } 
     else { 
      shadowLayer.startPoint = CGPointMake(1, 0.5); 
      shadowLayer.endPoint = CGPointMake(0, 0.5); 
      shadowAniOpacity = (anchorPoint.x)?0.32:0.24; 
     } 
    } 
    else{ 
     CGFloat layerHeight; 
     if (anchorPoint.y == 0) //from top 
     { 
      layerHeight = image.size.height - frame.origin.y; 
      jointLayer.frame = CGRectMake(0, 0, frame.size.width, layerHeight); 
      if (frame.origin.y) { 
       jointLayer.position = CGPointMake(frame.size.width/2, frame.size.height); 
      } 
      else { 
       jointLayer.position = CGPointMake(frame.size.width/2, 0); 
      } 
     } 
     else { //from bottom 
      layerHeight = frame.origin.y + frame.size.height; 
      jointLayer.frame = CGRectMake(0, 0, frame.size.width, layerHeight); 
      jointLayer.position = CGPointMake(frame.size.width/2, layerHeight); 
     } 

     //map image onto transform layer 
     imageLayer.frame = CGRectMake(0, 0, frame.size.width, frame.size.height); 
     imageLayer.anchorPoint = anchorPoint; 
     imageLayer.position = CGPointMake(frame.size.width/2, layerHeight*anchorPoint.y); 
     [jointLayer addSublayer:imageLayer]; 
     CGImageRef imageCrop = CGImageCreateWithImageInRect(image.CGImage, frame); 
     imageLayer.contents = (__bridge id)imageCrop; 
     imageLayer.backgroundColor = [UIColor clearColor].CGColor; 

     //add shadow 
     NSInteger index = frame.origin.y/frame.size.height; 
     shadowLayer.frame = imageLayer.bounds; 
     shadowLayer.backgroundColor = [UIColor darkGrayColor].CGColor; 
     shadowLayer.opacity = 0.0; 
     shadowLayer.colors = [NSArray arrayWithObjects:(id)[UIColor blackColor].CGColor, (id)[UIColor clearColor].CGColor, nil]; 
     if (index%2) { 
      shadowLayer.startPoint = CGPointMake(0.5, 0); 
      shadowLayer.endPoint = CGPointMake(0.5, 1); 
      shadowAniOpacity = (anchorPoint.x)?0.24:0.32; 
     } 
     else { 
      shadowLayer.startPoint = CGPointMake(0.5, 1); 
      shadowLayer.endPoint = CGPointMake(0.5, 0); 
      shadowAniOpacity = (anchorPoint.x)?0.32:0.24; 
     } 
    } 

    [imageLayer addSublayer:shadowLayer]; 

    //animate open/close animation 
    CABasicAnimation* animation = (anchorPoint.y == 0.5)?[CABasicAnimation animationWithKeyPath:@"transform.rotation.y"]:[CABasicAnimation animationWithKeyPath:@"transform.rotation.x"]; 
    [animation setDuration:duration]; 
    [animation setFromValue:[NSNumber numberWithDouble:start]]; 
    [animation setToValue:[NSNumber numberWithDouble:end]]; 
    [animation setRemovedOnCompletion:NO]; 
    [jointLayer addAnimation:animation forKey:@"jointAnimation"]; 

    //animate shadow opacity 
    animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 
    [animation setDuration:duration]; 
    [animation setFromValue:[NSNumber numberWithDouble:(start)?shadowAniOpacity:0]]; 
    [animation setToValue:[NSNumber numberWithDouble:(start)?0:shadowAniOpacity]]; 
    [animation setRemovedOnCompletion:NO]; 
    [shadowLayer addAnimation:animation forKey:nil]; 

    return jointLayer; 
} 
+0

修复格式请。 – Andy 2014-12-03 11:41:55

不管你用 CGImageCreateWithImageInRect创建

应该被释放,因为这是从非托管内存土地的功能。

  1. 使用CGImageRelease释放参照非托管对象:

    CGImageRelease(imageCrop); 
    imageCrop = NULL; 
    

OR

  1. 使用__bridge_transfer代替__bridge到将对象所有权通过CGImageRef转移给ARC。

    imageLayer.contents = (__bridge_transfer id)imageCrop; 
    

    在这种情况下,ARC将有效地为您做#1。

  2. 好读:

    1. 上有桥在Objective-C大后:https://stackoverflow.com/a/17256947/351305
    2. 及相关问题:Does ARC work with Core Graphics objects?
开始=>
+1

非常感谢。 @Andy – 2014-12-03 13:39:39

+0

@asheeshVerma很乐于帮助:-) – Andy 2014-12-03 13:41:28

+0

@asheeshVerma请将我的答案标记为正确,以便我可以获得免费的糖果和更多的名气。谢谢。 – Andy 2014-12-03 14:21:18