3

我正在编写一个需要一次在内存中保存大约 40 个 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
6 月 8 日星期一 16:37:20 未知 SpringBoard[22]:内存级别很关键 (5%)。没有要杀死的应用程序。将杀死 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 应用程序真的只能使用 1 兆字节的内存吗?

4

2 回答 2

15

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

未压缩的图像肯定会大于 JPEG 格式的压缩图像占用的 44 KiB(大约 3 或 4 字节乘以宽度和高度)。因此,仅查看 JPEG 大小时,内存耗尽的速度比您想象的要快。

如果您真的只需要将 JPEG 保存在内存中(并且什么都不做,只保存它们),您可以考虑将原始字节流存储在内存中,然后仅在您真正需要时将其作为图像加载。

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

于 2009-06-08T23:55:46.507 回答
1

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

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

具体来说,您应该能够:

[UIImage imageWithContentsOfFile:[[UIBundle mainBundle] pathForResource:@"filename" ofType:@"jpeg"]];
于 2009-06-09T00:13:11.713 回答