IOS在图像内存泄漏上绘制图像

时间:2012-08-09 04:42:23

标签: memory-leaks uiimage core-graphics retina-display drawimage

我正在尝试使用下面的方法在UIImageView中绘制文本。 问题是该方法是从循环内部调用的,该循环迭代32次(在这种特定情况下)。我在14号电话“准备好文字图片”之后就死了。

不幸的是,当我使用乐器寻找泄漏时,应用程序会在我得到任何东西之前死掉。 我不太确定我应该发布什么,或者是否有更好的方法来做到这一点。

谢谢!

-(void) writeNameToImage:(int)soundIndex setNumber:(int)setNumber
{

    NSString* strTextToWrite;

    if(setNumber==1)
        strTextToWrite= ((MyObject*)[arrObjects1 objectAtIndex:soundIndex-1]).soundName;
    else 
        strTextToWrite= ((MyObject*)[arrObjects2 objectAtIndex:soundIndex-1]).soundName;

    NSLog(@"string to draw: %@",strTextToWrite);
    //Retrieve image from UIImageView
    UIImage* layerToUpdate= imgViewRecorded.image;


    //***** Drawing the text image.
    UIFont *font = [UIFont boldSystemFontOfSize:15.0];
    CGSize size  = [strTextToWrite sizeWithFont:font];

    UIGraphicsBeginImageContextWithOptions(size,NO,0.0);


    // draw in context, you can use also drawInRect:withFont:
    [[UIColor whiteColor] set];
    [strTextToWrite drawAtPoint:CGPointMake(0.0, 0.0) withFont:font];

    // transfer image
    UIImage* imgToAdd = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    NSLog(@"text image ready");
    //**** Finished drawing text image

    //**** Updating layer image with generated image
    UIGraphicsBeginImageContextWithOptions(layerToUpdate.size, FALSE, 0.0);
    NSLog(@"layer created in context");
    [layerToUpdate drawInRect:CGRectMake( 0, 0, layerToUpdate.size.width, layerToUpdate.size.height)];

    //translate to the center
    CGContextTranslateCTM( UIGraphicsGetCurrentContext(), 0.5f * layerToUpdate.size.width, 0.5f * layerToUpdate.size.height ) ;
    //rotate with the center of the image as the rotation point
    CGContextRotateCTM(UIGraphicsGetCurrentContext(), CC_DEGREES_TO_RADIANS( degrees ) );
    //translate back to original position
    CGContextTranslateCTM( UIGraphicsGetCurrentContext(), -0.5f *layerToUpdate.size.width, -0.5f *layerToUpdate.size.height ) ;

    if(setNumber==1)
        [imgToAdd drawInRect:CGRectMake( (303-(imgToAdd.size.width/2)), 80, imgToAdd.size.width, imgToAdd.size.height)];
    else
        [imgToAdd drawInRect:CGRectMake( (303-(imgToAdd.size.width/2)), 23, imgToAdd.size.width, imgToAdd.size.height)];

    NSLog(@"text drawn to layer");

    CGContextRotateCTM(UIGraphicsGetCurrentContext(), CC_DEGREES_TO_RADIANS( degrees ) );
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    //[layerToUpdate release];
    NSLog(@"assigning new created image");
    imgViewRecorded.image = newImage;

}

我注意到如果我在方法结束时添加[newImage release],它会完全运行,但显然会导致EXC_BAD_ACCESS。

更新

我尝试过其他解决方案,但在这种情况下,文字逐渐变得模糊。这意味着我绘制的第一个文本是最模糊的,最后一个文本看起来非常清晰。我认为这可能是由于视网膜规模,但我不知道如何解决这个问题。

-(void) writeSoundNameToImage:(int)soundIndex setNumber:(int)setNumber
{

    NSString* strTextToWrite;

    if(setNumber==1)
        strTextToWrite= ((MyObject*)[arrObjects1 objectAtIndex:soundIndex-1]).soundName;
    else 
        strTextToWrite= ((MyObject*)[arrObjects2 objectAtIndex:soundIndex-1]).soundName;


    NSLog(@"string to draw: %@",strTextToWrite);


    //***** Drawing the text image.
    UIFont *font = [UIFont boldSystemFontOfSize:15.0];
    CGSize size  = [strTextToWrite sizeWithFont:font];



    UIImage* layerToUpdate= imgViewRecorded.image;

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGFloat scale = [[UIScreen mainScreen] scale];
    CGContextRef context = CGBitmapContextCreate( NULL,layerToUpdate.size.width,layerToUpdate.size.height, 8, 4  * layerToUpdate.size.width, colorSpace, kCGImageAlphaPremultipliedFirst);


    CGContextDrawImage(context, CGRectMake(0, 0, layerToUpdate.size.width, layerToUpdate.size.height), layerToUpdate.CGImage);


    //translate to the center
    CGContextTranslateCTM( context, 0.5f * layerToUpdate.size.width, 0.5f * layerToUpdate.size.height ) ;
    //rotate with the center of the image as the rotation point
    CGContextRotateCTM(context, -CC_DEGREES_TO_RADIANS( ((soundIndex-1)*self.myProfile.degreesPerSound)+self.myProfile.degreesPerSound/2 ) );
    //translate back to original position
    CGContextTranslateCTM( context, -0.5f*layerToUpdate.size.width, -0.5f*layerToUpdate.size.height ) ;

    char* text = (char *)[strTextToWrite cStringUsingEncoding:NSASCIIStringEncoding];
    CGContextSelectFont(context, "Helvetica", 15, kCGEncodingMacRoman);
    CGContextSetTextDrawingMode(context, kCGTextFillStroke);

    CGContextSetRGBFillColor(context, 255, 255, 255, 1);
    CGContextSetRGBStrokeColor(context, 255, 255, 255, 1);

    if(setNumber==1)
        CGContextShowTextAtPoint(context, (303-(size.width/2)), 600-90, text, strlen(text));
    else
        CGContextShowTextAtPoint(context, (303-(size.width/2)), 600-33, text, strlen(text));

    CGContextRotateCTM(context, -CC_DEGREES_TO_RADIANS( ((soundIndex-1)*self.myProfile.degreesPerSound)+self.myProfile.degreesPerSound/2 ) );

    //CGContextScaleCTM(context, layerToUpdate.size.width/scale, layerToUpdate.size.height/scale);

    CGImageRef imageMasked = CGBitmapContextCreateImage(context);

    UIImage* newImage=[UIImage imageWithCGImage:imageMasked scale:scale orientation:UIImageOrientationUp];

    imgViewRecorded.image =newImage;



    CGImageRelease(imageMasked);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);

}

1 个答案:

答案 0 :(得分:0)

在我的特殊情况下,由于这是用于图像初始化,我最终做了以下操作。

UIImage* layerToUpdate= imgViewRecorded.image;

UIGraphicsBeginImageContextWithOptions(layerToUpdate.size, FALSE, 0.0);


NSLog(@"layer created in context");
[layerToUpdate drawInRect:CGRectMake( 0, 0, layerToUpdate.size.width, layerToUpdate.size.height)];
UIFont *font = [UIFont boldSystemFontOfSize:15.0];
[[UIColor whiteColor] set];

for (int i=0; i<self.myProfile.totalSounds; i++)
{ 
    //translate to the center
    CGContextTranslateCTM( UIGraphicsGetCurrentContext(), 0.5f * layerToUpdate.size.width, 0.5f * layerToUpdate.size.height ) ;
    //rotate with the center of the image as the rotation point
    CGContextRotateCTM(UIGraphicsGetCurrentContext(), degrees );
    //translate back to original position
    CGContextTranslateCTM( UIGraphicsGetCurrentContext(), -0.5f *layerToUpdate.size.width, -0.5f *layerToUpdate.size.height ) ;

    NSString* strTextToWrite;

    //do set one first
    strTextToWrite= ((MyObject*)[arrObjects1 objectAtIndex:soundIndex-1]).soundName;
    CGSize size  = [strTextToWrite sizeWithFont:font];

    [strTextToWrite drawAtPoint:CGPointMake((303-(size.width/2)), 80.0) withFont:font];

    //do set 2
    strTextToWrite= ((MyObject*)[arrObjects2 objectAtIndex:soundIndex-1]).soundName;
    size  = [strTextToWrite sizeWithFont:font];

    [strTextToWrite drawAtPoint:CGPointMake((303-(size.width/2)), 23.0) withFont:font];

    //translate to the center
    CGContextTranslateCTM( UIGraphicsGetCurrentContext(), 0.5f * layerToUpdate.size.width, 0.5f * layerToUpdate.size.height ) ;
    //rotate back
    CGContextRotateCTM(UIGraphicsGetCurrentContext(), -degrees );
    //translate back to original position
    CGContextTranslateCTM( UIGraphicsGetCurrentContext(), -0.5f *layerToUpdate.size.width, -0.5f *layerToUpdate.size.height ) ;
}

UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

imgViewRecorded.image =  newImage;

两者之间的区别很明显我过去创建了几个上下文而不知道他们的资源何时会被释放导致内存泄漏和应用程序退出。在后一个中,我创建了一个独特的上下文并操纵它来绘制我需要绘制的所有文本。

希望这对某人有用。