tldr:ImagedNamed很好。它可以很好地处理内存。使用它,不必担心。
编辑2012年11月:请注意,这个问题可以追溯到iOS 2.0!从那时起,图像要求和处理方式发生了很大变化。视网膜使图像更大,加载图像稍微复杂一些。借助对iPad和视网膜图像的内置支持,您当然应该在代码中使用ImageNamed。现在,为了后代的缘故:
在妹妹线程在苹果开发论坛收到一些更好的交通。特别是Rincewind增加了一些权限。
iPhone OS 2.x中存在一些问题,即使在出现内存警告后,imageNamed:缓存也不会被清除。同时,+ imageNamed:已得到很多使用,而不是用于高速缓存,而是为了方便起见,这可能使问题更加严重。
同时警告
在速度方面,人们对正在发生的事情普遍存在误解。+ imageNamed:要做的最大的事情是解码源文件中的图像数据,这几乎总是显着增大数据大小(例如,屏幕大小的PNG文件在压缩时可能会消耗数十KB,但会消耗一半以上的MB解压缩-宽度*高度* 4)。相比之下,+ imageWithContentsOfFile:每次需要图像数据时都会对该图像进行解压缩。可以想象,如果只需要一次图像数据,那么在这里就什么也赢不了,除了有图像的缓存版本,而且可能需要的时间更长。但是,如果确实有一个大图像需要经常重绘,那么有其他选择,尽管我主要建议您避免重绘该大图像:)。
关于缓存的一般行为,它会根据文件名进行缓存(因此+ imageNamed:具有相同名称的两个实例应导致对相同的缓存数据的引用),并且当您通过以下方式请求更多图像时,缓存将动态增长+ imageNamed :。在iPhone OS 2.x上,错误会阻止在收到内存警告时缩小缓存。
和
我的理解是+ imageNamed:缓存应遵守iPhone OS 3.0上的内存警告。如果有机会请进行测试,如果发现不是这种情况,请报告错误。
所以你有它。imageNamed:不会破坏您的窗户或谋杀您的孩子。这很简单,但是它是一种优化工具。可悲的是,它的名字不好用,而且没有任何一个等值的易用性-因此,人们在使用它时,过度使用它并感到不高兴。
我向UIImage添加了一个类别来解决此问题:
// header omitted
// Before you waste time editing this, please remember that a semi colon at the end of a method definition is valid and a matter of style.
+ (UIImage*)imageFromMainBundleFile:(NSString*)aFileName; {
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
return [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@", bundlePath,aFileName]];
}
Rincewind还提供了一些示例代码来构建您自己的优化版本。我看不出值得维护,但这里是为了完整性。
CGImageRef originalImage = uiImage.CGImage;
CFDataRef imageData = CGDataProviderCopyData(
CGImageGetDataProvider(originalImage));
CGDataProviderRef imageDataProvider = CGDataProviderCreateWithCFData(imageData);
CFRelease(imageData);
CGImageRef image = CGImageCreate(
CGImageGetWidth(originalImage),
CGImageGetHeight(originalImage),
CGImageGetBitsPerComponent(originalImage),
CGImageGetBitsPerPixel(originalImage),
CGImageGetBytesPerRow(originalImage),
CGImageGetColorSpace(originalImage),
CGImageGetBitmapInfo(originalImage),
imageDataProvider,
CGImageGetDecode(originalImage),
CGImageGetShouldInterpolate(originalImage),
CGImageGetRenderingIntent(originalImage));
CGDataProviderRelease(imageDataProvider);
UIImage *decompressedImage = [UIImage imageWithCGImage:image];
CGImageRelease(image);
使用此代码的权衡在于,解码后的图像使用更多的内存,但渲染速度更快。