应用程序因内存压力而崩溃

时间:2014-01-22 13:15:07

标签: ios objective-c xcode memory-leaks cgcontext

这里我正在生成UIViews的图像,为此我使用以下代码:

    // ======================== Create PDF FROM Images     ============================

- (void) drawBorder
{
    CGContextRef    currentContext = UIGraphicsGetCurrentContext();
    UIColor *borderColor = [UIColor grayColor];

    CGRect rectFrame = CGRectMake(kBorderInset, kBorderInset, pageSize.width-kBorderInset*2, pageSize.height-kBorderInset*2);

    CGContextSetStrokeColorWithColor(currentContext, borderColor.CGColor);
    CGContextSetLineWidth(currentContext, kBorderWidth);
    CGContextStrokeRect(currentContext, rectFrame);

    //CGContextRelease(currentContext);
}

- (void)drawPageNumber:(NSInteger)pageNumber
{
    NSString* pageNumberString = [NSString stringWithFormat:@"Page %d", pageNumber];
    UIFont* theFont = [UIFont systemFontOfSize:12];

    CGSize pageNumberStringSize = [pageNumberString sizeWithFont:theFont
                                               constrainedToSize:pageSize
                                                   lineBreakMode:NSLineBreakByWordWrapping];

    CGRect stringRenderingRect = CGRectMake(kBorderInset,
                                            pageSize.height - 40.0,
                                            pageSize.width - 2*kBorderInset,
                                            pageNumberStringSize.height);

    [pageNumberString drawInRect:stringRenderingRect withFont:theFont lineBreakMode:NSLineBreakByWordWrapping alignment:NSTextAlignmentCenter];
}

- (void) drawHeader:(int)i;
{
    CGContextRef    currentContext = UIGraphicsGetCurrentContext();
    //CGContextSetRGBFillColor(currentContext, 0.3, 0.7, 0.2, 1.0);

    CGContextSetRGBFillColor(currentContext, 0.0f, 0.0f, 0.0f, 1);

    //NSString *textToDraw = [NSString stringWithFormat:@"%@: %@ \n\nDate Range: %@ \n\nNumber of observations: %@",appDelegate.teacherName,@"Curriculum report",lblDate.text,lblNoOf.text];
    NSString *textToDraw;

    if(i<[arrReportTitles count])
        textToDraw=[arrReportTitles objectAtIndex:i];

    UIFont *font = [UIFont systemFontOfSize:16.0];

    CGSize stringSize = [textToDraw sizeWithFont:font constrainedToSize:CGSizeMake(pageSize.width - 2*kBorderInset-2*kMarginInset, pageSize.height - 2*kBorderInset - 2*kMarginInset) lineBreakMode:NSLineBreakByWordWrapping];

    CGRect renderingRect = CGRectMake(kBorderInset + kMarginInset, kBorderInset + kMarginInset, pageSize.width - 2*kBorderInset - 2*kMarginInset, stringSize.height);

    [textToDraw drawInRect:renderingRect withFont:font lineBreakMode:NSLineBreakByWordWrapping alignment:NSTextAlignmentLeft];

    //CGContextRelease(currentContext);
}

- (void) drawText
{
    CGContextRef    currentContext = UIGraphicsGetCurrentContext();
    CGContextSetRGBFillColor(currentContext, 0.0, 0.0, 0.0, 1.0);
    NSString *textToDraw = @"TeachersEvaluation";
    UIFont *font = [UIFont systemFontOfSize:24.0];
    CGSize stringSize = [textToDraw sizeWithFont:font
                               constrainedToSize:CGSizeMake(pageSize.width - 2*kBorderInset-2*kMarginInset, pageSize.height - 2*kBorderInset - 2*kMarginInset)
                                   lineBreakMode:NSLineBreakByWordWrapping];

    CGRect renderingRect = CGRectMake(kBorderInset + kMarginInset + 375, kBorderInset + kMarginInset + 450.0, pageSize.width - 2*kBorderInset - 2*kMarginInset, stringSize.height-50);
    [textToDraw drawInRect:renderingRect
                  withFont:font
             lineBreakMode:NSLineBreakByWordWrapping
                 alignment:NSTextAlignmentLeft];

    //CGContextRelease(currentContext);
}

- (void) drawLine
{
    CGContextRef    currentContext = UIGraphicsGetCurrentContext();

    CGContextSetLineWidth(currentContext, kLineWidth);

    CGContextSetStrokeColorWithColor(currentContext, [UIColor grayColor].CGColor);

    CGPoint startPoint = CGPointMake(kMarginInset + kBorderInset, kMarginInset + kBorderInset + 120.0);
    CGPoint endPoint = CGPointMake(pageSize.width - 2*kMarginInset -2*kBorderInset, kMarginInset + kBorderInset + 120.0);

    CGContextBeginPath(currentContext);
    CGContextMoveToPoint(currentContext, startPoint.x, startPoint.y);
    CGContextAddLineToPoint(currentContext, endPoint.x, endPoint.y);

    CGContextClosePath(currentContext);
    CGContextDrawPath(currentContext, kCGPathFillStroke);

    //CGContextRelease(currentContext);
}

-(NSInteger) getImageHeighAndWidht : (NSInteger) value
{
    value = value / 2;

    if (value > 800 ) {

        [self getImageHeighAndWidht:value];

    }

    if (value<450) {

        value = value + (value/2);

    }

    return value;
}

- (void) drawImage: (UIImage *)fileName
{
    CGSize mainImageSize;
    UIImage *mainImage;

    if (fileName.size.width > 542 || fileName.size.height > 742)
    {
        if (fileName.size.height > fileName.size.width) {

            mainImageSize = CGSizeMake(470,575);
            mainImage =fileName; //[fileName scaleProportionalToSize:mainImageSize];

        } else {

            mainImageSize = CGSizeMake(290,395);
            mainImage = fileName;//[fileName scaleProportionalToSize:mainImageSize];

        }

    } else {

        mainImageSize = CGSizeMake(fileName.size.width,fileName.size.height);
        mainImage =fileName; //[fileName scaleProportionalToSize:mainImageSize];
    }

    float imageWidht;
    if (mainImage.size.width > 542)
    {
        imageWidht = 542;
    } else {
        imageWidht = mainImage.size.width;
    }

    float imageHeight;
    if (mainImage.size.height > 575)
    {
        imageHeight = 600.0;
    } else {
        imageHeight = mainImage.size.height;
    }

    //UIImage * demoImage = [UIImage imageNamed:fileName];
    [mainImage drawInRect:CGRectMake( (pageSize.width - imageWidht)/2, 150, imageWidht, imageHeight)];
}

- (void) generatePdfWithFilePath: (NSString *)thefilePath
{
    UIGraphicsBeginPDFContextToFile(thefilePath, CGRectZero, nil);

    NSInteger currentPage = 0;

//    _imgViewScreenShot.image=[arrMultiplePhots objectAtIndex:0];
//    _imgViewScreenShot2.image=[arrMultiplePhots objectAtIndex:1];


    for(int i = 0; i < [arrMultiplePhots count]; i++){

        //Start a new page.
        UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);

        //Draw a page number at the bottom of each page.
        currentPage++;
        [self drawPageNumber:currentPage];

        //Draw a border for each page.
        [self drawBorder];

        //Draw text fo our header.
        [self drawHeader:i];

        //Draw a line below the header.
        [self drawLine];

        //if(i == 0) {
        //currImage = [self.view imageByRenderingView];

        //_imgViewScreenShot.image=currImage;
        [self drawImage:[arrMultiplePhots objectAtIndex:i]];
        //}
    }

    // Close the PDF context and write the contents out.
    UIGraphicsEndPDFContext();
}

但是当我在循环内连续生成多个视图的图像时,我的应用程序崩溃并发出警告“应用程序因内存压力而崩溃”。

我使用仪器工具找出这次崩溃背后的原因,并且我在所有这些功能周围都有内存泄漏警告。

那么如何在上面的代码中解决这个内存泄漏问题?

修改

使用自动释放后,

在上述功能中删除了内存泄漏

现在我在这个函数中出现内存泄漏

生成图像

- (UIImage *)imageByRenderingView
{
    UIGraphicsBeginImageContext(self.bounds.size);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return resultingImage;
}

1 个答案:

答案 0 :(得分:1)

尝试此更改并告诉我它是否有帮助:

- (void) generatePdfWithFilePath: (NSString *)thefilePath
{
    UIGraphicsBeginPDFContextToFile(thefilePath, CGRectZero, nil);

    NSInteger currentPage = 0;

//    _imgViewScreenShot.image=[arrMultiplePhots objectAtIndex:0];
//    _imgViewScreenShot2.image=[arrMultiplePhots objectAtIndex:1];


    for(int i = 0; i < [arrMultiplePhots count]; i++)
    {
        @autoreleasepool {
            //Start a new page.
            UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, pageSize.width, pageSize.height), nil);

            //Draw a page number at the bottom of each page.
            currentPage++;
            [self drawPageNumber:currentPage];

            //Draw a border for each page.
            [self drawBorder];

            //Draw text fo our header.
            [self drawHeader:i];

            //Draw a line below the header.
            [self drawLine];

            //if(i == 0) {
            //currImage = [self.view imageByRenderingView];

            //_imgViewScreenShot.image=currImage;
            [self drawImage:[arrMultiplePhots objectAtIndex:i]];
            //}
        }
    }

    // Close the PDF context and write the contents out.
    UIGraphicsEndPDFContext();
}