首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iPhone - UIImage泄漏,CGBitmapContextCreateImage泄漏

iPhone - UIImage泄漏,CGBitmapContextCreateImage泄漏
EN

Stack Overflow用户
提问于 2009-09-15 14:18:24
回答 8查看 4.4K关注 0票数 5

好吧,我有一个世界的困难追查这个内存泄漏。运行此脚本时,我没有看到任何内存泄漏,但我的objectalloc正在攀升。Instruments指向CGBitmapContextCreateImage > create_bitmap_data_provider > malloc,这占据了我的objectalloc的60%。

使用NSTimer多次调用此代码。

代码语言:javascript
复制
 //GET IMAGE FROM RESOURCE DIR
  NSString * fileLocation = [[NSBundle mainBundle] pathForResource:imgMain ofType:@"jpg"];
  NSData * imageData = [NSData dataWithContentsOfFile:fileLocation];
  UIImage * blurMe = [UIImage imageWithData:imageData];

  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    UIImage * scaledImage = [blurMe _imageScaledToSize:CGSizeMake(blurMe.size.width / dblBlurLevel, blurMe.size.width / dblBlurLevel) interpolationQuality:3.0];
    UIImage * labelImage = [scaledImage _imageScaledToSize:blurMe.size interpolationQuality:3.0];
    UIImage * imageCopy = [[UIImage alloc] initWithCGImage:labelImage.CGImage];

  [pool drain]; // deallocates scaledImage and labelImage

  imgView.image = imageCopy;
  [imageCopy release];

下面是模糊函数。我相信objectalloc的问题就在这里。也许我只需要一双清新的眼睛。如果有人能解决这个问题就太好了。对不起,它有点长...我会试着缩短它。

代码语言:javascript
复制
    @implementation UIImage(Blur)
    - (UIImage *)blurredCopy:(int)pixelRadius
    {
        //VARS
        unsigned char *srcData, *destData, *finalData;
        CGContextRef    context = NULL;
        CGColorSpaceRef colorSpace;
        void *          bitmapData;
        int             bitmapByteCount;
        int             bitmapBytesPerRow;

        //IMAGE SIZE
        size_t pixelsWide = CGImageGetWidth(self.CGImage);
        size_t pixelsHigh = CGImageGetHeight(self.CGImage);
        bitmapBytesPerRow   = (pixelsWide * 4);
        bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);

        colorSpace = CGColorSpaceCreateDeviceRGB();
        if (colorSpace == NULL) { return NULL; }

        bitmapData = malloc( bitmapByteCount );
        if (bitmapData == NULL) { CGColorSpaceRelease( colorSpace ); }

        context = CGBitmapContextCreate (bitmapData,
                         pixelsWide,
                         pixelsHigh,
                         8,    
                         bitmapBytesPerRow,
                         colorSpace,
                         kCGImageAlphaPremultipliedFirst );
        if (context == NULL) { free (bitmapData); }

        CGColorSpaceRelease( colorSpace );
        free (bitmapData);

        if (context == NULL) { return NULL; }

        //PREPARE BLUR
        size_t width = CGBitmapContextGetWidth(context);
        size_t height = CGBitmapContextGetHeight(context);
        size_t bpr = CGBitmapContextGetBytesPerRow(context);
        size_t bpp = (CGBitmapContextGetBitsPerPixel(context) / 8);
        CGRect rect = {{0,0},{width,height}}; 

        CGContextDrawImage(context, rect, self.CGImage); 

        // Now we can get a pointer to the image data associated with the bitmap
        // context.
        srcData = (unsigned char *)CGBitmapContextGetData (context);
        if (srcData != NULL)
        {

            size_t dataSize = bpr * height;
            finalData = malloc(dataSize);
            destData = malloc(dataSize);
            memcpy(finalData, srcData, dataSize);
            memcpy(destData, srcData, dataSize);

            int sums[5];
            int i, x, y, k;
            int gauss_sum=0;
            int radius = pixelRadius * 2 + 1;
            int *gauss_fact = malloc(radius * sizeof(int));

            for (i = 0; i < pixelRadius; i++)
            {
            .....blah blah blah...
                THIS IS JUST LONG CODE THE CREATES INT FIGURES
                ........blah blah blah......
                }


            if (gauss_fact) { free(gauss_fact); }
        }

        size_t bitmapByteCount2 = bpr * height;
       //CREATE DATA PROVIDER
        CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, srcData, bitmapByteCount2, NULL);

       //CREATE IMAGE
        CGImageRef cgImage = CGImageCreate(
                               width, 
                               height, 
                               CGBitmapContextGetBitsPerComponent(context),
                               CGBitmapContextGetBitsPerPixel(context), 
                               CGBitmapContextGetBytesPerRow(context),
                               CGBitmapContextGetColorSpace(context), 
                               CGBitmapContextGetBitmapInfo(context), 
                               dataProvider, 
                               NULL, 
                               true, 
                               kCGRenderingIntentDefault
                                     );

       //RELEASE INFORMATION
        CGDataProviderRelease(dataProvider);
        CGContextRelease(context); 

        if (destData) { free(destData); }
        if (finalData) { free(finalData); }
        if (srcData) { free(srcData); }


        UIImage *retUIImage = [UIImage imageWithCGImage:cgImage];
        CGImageRelease(cgImage);

        return retUIImage;
  }

我能想到的唯一一件事就是阻塞对象锁,这个UIImage *retUIImage = UIImage imageWithCGImage:cgImage;...but返回后如何释放它?希望有人能帮上忙。

EN

回答 8

Stack Overflow用户

发布于 2010-03-19 01:57:27

我已经使用Quartz很多次了。每次我这样做都是一场噩梦。据我所知,我已经填补了苹果发送一个项目作为崩溃证据的错误,有4件事是真的:

  1. Quartz泄漏如地狱
  2. 释放内存耗时太长
  3. 不必要地使用太多内存或
  4. 所有这些内存的组合。

我曾经创建了一个简单的项目来证明这一点。这个项目有一个按钮。每次按下按钮时,屏幕上都会添加一个小图像(100x100像素)。图像由两个层组成,一个是图像本身,另一个是包含在图像边界周围绘制的虚线的附加层。这幅画是用Quartz完成的。按下8次按钮会使应用程序崩溃。你可以说:按下按钮8次,屏幕上添加了16个图像,这就是崩溃的原因,对吧?

而不是使用Quartz绘制边界,我决定在PNG上预先绘制边界,并将其作为图层添加到对象中。每个对象创建两个相同的层。对吗?

我点击了100次,在屏幕上添加了200张图片,没有崩溃。内存从未超过800 Kb。我可以继续点击...这个应用程序继续变得更快更快。没有内存警告,没有崩溃。

苹果不得不紧急审查Quartz。

票数 4
EN

Stack Overflow用户

发布于 2010-01-08 22:23:18

获取clang并通过它运行您的项目。它不仅可以找到您的(静态)泄漏,还可以帮助您更多地了解引用计数规则--至少对我来说是这样。

票数 1
EN

Stack Overflow用户

发布于 2009-09-25 16:26:47

我看到过类似的行为,也读过其他几篇类似的帖子。创建一个自动释放池似乎没有帮助。看起来这个库要么是在泄漏内存,要么是把它存储在一个更高级别的自动释放池中,所以直到发布时才会太晚。我怀疑框架中有一个bug,但无法证明。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1427478

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档