iphone - 从文档目录读取图像时内存泄漏

标签 iphone

我正在循环读取文档目录中的图像。

for(iArrCount=0;iArrCount<[arrImages count];iArrCount++)
    {
UIButton *btnImage = [UIButton buttonWithType:UIButtonTypeCustom];
            btnImage.frame = CGRectMake(xRow, yRow, width, height);
            [btnImage addTarget:self action:@selector(imageDetails:) forControlEvents:UIControlEventTouchUpInside];
            btnImage.tag = iCount;
            if(iCount<[arrImages count])
            {


                NSString *workSpacePath=[[self applicationDocumentsDirectory] stringByAppendingPathComponent:[arrImages objectAtIndex:iCount]];
                [btnImage setBackgroundImage:[UIImage imageWithData:[NSData dataWithContentsOfFile:workSpacePath]] forState:UIControlStateNormal];
                [scrollImages addSubview:btnImage];
}
}  

这样做时,控制权将转移到 didRecieveMemoryWarning 并且应用程序崩溃。如果我用资源文件夹中的图像替换图像,应用程序不会崩溃。为什么这样?

最佳答案

问题在于您的按钮正在维护对全分辨率图像的引用。您需要做的是将图像缩小到按钮尺寸,并将缩小的图像设置为按钮背景。像这样的事情应该可以解决问题:

在 UIImage 上创建一个类别...我们称之为 UIImage+Scaler.h

// UIImage+Scaler.h
#import <UIKit/UIKit.h>

@interface UIImage (Scaler)
- (UIImage*)scaleToSize:(CGSize)size;
@end

以及实现:

// UIImage+Scaler.m
#import "UIImage+Scaler.h"

#define kBitsPerComponent 8
#define kBitmapInfo       kCGImageAlphaPremultipliedLast

- (UIImage*)scaleToSize:(CGSize)size
{
    CGBitmapInfo bitmapInfo = kBitmapInfo;
    size_t bytesPerRow = size.width * 4.0;
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL, size.width, 
                                   size.height, kBitsPerComponent, 
                                   bytesPerRow, colorSpace, bitmapInfo);

    CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
    CGContextDrawImage(context, rect, self.CGImage);

    CGImageRef scaledImageRef = CGBitmapContextCreateImage(context);
    UIImage* scaledImage = [UIImage imageWithCGImage:scaledImageRef];

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

    return scaledImage;
}

好的,现在回到你的代码。就像其他海报所说的那样,您需要一个自动释放池。

CGSize buttonSize = CGSizeMake(width, height);

for(iArrCount=0;iArrCount<[arrImages count];iArrCount++)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    UIButton *btnImage = [UIButton buttonWithType:UIButtonTypeCustom];
    btnImage.frame = CGRectMake(xRow, yRow, width, height);
    [btnImage addTarget:self 
                 action:@selector(imageDetails:)      
       forControlEvents:UIControlEventTouchUpInside];
    btnImage.tag = iCount;
    if(iCount<[arrImages count])
    {
        NSString *workSpacePath=[[self applicationDocumentsDirectory]  
                       stringByAppendingPathComponent:
                            [arrImages objectAtIndex:iCount]];
        UIImage* bigImage = [UIImage imageWithData:[NSData   
                             dataWithContentsOfFile:workSpacePath]];
        UIImage* smallImage = [bigImage scaleToSize:buttonSize];
        [btnImage setBackgroundImage:smallImage forState:UIControlStateNormal];
        [scrollImages addSubview:btnImage];
    }
    [pool drain]; // must drain pool inside loop to release bigImage
} 

希望这能解决问题。

关于iphone - 从文档目录读取图像时内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11359383/

相关文章:

iphone - MFMessageComposeViewController 停止短信

iphone - 如何在 iOS 中减少 "Live Bytes"?

ios - 将图像从 Google Places Photo JSON 返回到 imageView

iphone - 仅在 reloadData 完成后调用函数

ios - 与UIWebView相比,WKWebView重定向问题

iphone - 如何允许 a) 没有 CSRF token + SSL 的 HTTP 身份验证或 b) 需要带有设备的 CSRF token ?

iphone - 指向 void 的指针的算术(看起来很容易解决,但我不明白如何做到这一点)

iphone - iOS 中无休止的重复滚动/动画背景?

iphone - 从 iOS 照片库获取图片数据

ios - 方法未被调用 : - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken