为什么加载超过一兆字节的图像会占用我所有的iPhone内存?

时间:2009-06-08 23:48:22

标签: iphone memory uiimage memory-management

我正在编写一个应用程序,需要同时在内存中保存大约44 kb的JPEG。我听说应用程序在触发低内存警告之前可以使用大约22兆字节,所以我很确定它应该能够做到这一点。但是,一旦我传递了一个兆字节的负载,这些消息就会在控制台中弹出:

Mon Jun  8 16:37:19 unknown configd[21] : kernel memory event (90), free: 374, active: 1736, inactive: 959, purgeable: 0, wired: 6260
Mon Jun  8 16:37:20 unknown configd[21] : kernel memory event (95), free: 363, active: 876, inactive: 492, purgeable: 0, wired: 6241
Mon Jun  8 16:37:20 unknown SpringBoard[22] : Memory level is critical (5%). No apps to kill. Will kill SpringBoard
Mon Jun  8 16:37:24 unknown SpringBoard[22] : Jetsaming SpringBoard...

然后它将我转回主屏幕。

这是我用来加载图片的代码:

#define NUM_IMAGES 40

@interface MyClass : NSObject {
    UIImageView* imageView;
    UIImage* loadedImages[NUM_IMAGES];
}

- (void)initImages;

@property (nonatomic, retain) IBOutlet UIImageView* imageView;

@end


@implementation MyClass

@synthesize imageView;

- (void)initImages {
    int i;
    for (i = 0; i < NUM_IMAGES; i++) {
        loadedImages[i] = [UIImage imageNamed:[NSString stringWithFormat:IMAGE_FORMAT, i+1]];
    }
    imageView.image = loadedImages[0];
}

@end

我在这里做错了吗? iPhone应用程序真的只能使用一兆字节的内存吗?

2 个答案:

答案 0 :(得分:15)

当您加载压缩图像(例如JPEG图像)时,它通常会被解压缩(因为这是需要做的事情,以便您可以对图像执行一些有用的操作,例如显示或操作它)。

未压缩的图像肯定会大于JPEG格式的压缩图像所占的44 KiB(大约3或4个字节乘以宽度和高度)。因此,只要查看JPEG大小,就会比你想象的更快地耗尽内存。

如果你真的只需要将JPEG保存在内存中(并且只对它们执行任何操作,只需按住它们),您可以考虑将原始字节流存储在内存中,然后仅在您真正需要时才将其加载为图像。

但可能还有其他选择,具体取决于您需要做什么。你真的需要一次内存中的所有图像吗?您是否可以推迟加载单个图像直到需要(并在那时卸载其他图像)以节省内存?您是否只需要从每个可以缓存的图像中获取某些信息(之后您将不再需要图像本身)?等......

答案 1 :(得分:1)

imageNamed:将解压缩图像数据缓存未压缩的数据。如果您使用imageWithContentsOfFile:,我相信您会没事的,因为该方法只会存储压缩数据,并在绘制时动态解码。

查看SO问题的答案Dispelling the UIImage imageNamed: FUD

具体来说,您应该能够:

[UIImage imageWithContentsOfFile:[[UIBundle mainBundle] pathForResource:@"filename" ofType:@"jpeg"]];