我正在编写一个应用程序,需要同时在内存中保存大约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应用程序真的只能使用一兆字节的内存吗?
答案 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"]];