tldr: ImagedNamed в порядке. Он хорошо обрабатывает память. Используйте это и перестаньте беспокоиться.
Изменить ноябрь 2012 : обратите внимание, что этот вопрос относится к iOS 2.0! С тех пор требования к изображениям и их обработка сильно изменились. Retina увеличивает размер изображений и немного усложняет их загрузку. Благодаря встроенной поддержке изображений iPad и Retina вам непременно следует использовать ImageNamed в своем коде. А теперь для потомков:
Сестра нить на форумах Apple , Dev получил несколько лучше трафика. В частности, Ринсвинд добавил немного авторитета.
В iPhone OS 2.x есть проблемы, при которых кэш imageNamed: не очищается даже после предупреждения о памяти. В то же время + imageNamed: широко используется не для кеширования, а для удобства, что, вероятно, усугубило проблему больше, чем должно было быть.
предупреждая, что
Что касается скорости, то существует общее непонимание происходящего. Самая большая вещь, которую делает + imageNamed: - это декодирование данных изображения из исходного файла, что почти всегда значительно увеличивает размер данных (например, файл PNG размером с экран может занимать несколько десятков КБ при сжатии, но занимает более половины МБ. в распакованном виде - ширина * высота * 4). Напротив, + imageWithContentsOfFile: будет распаковывать это изображение каждый раз, когда требуются данные изображения. Как вы понимаете, если вам нужны данные изображения только один раз, вы ничего здесь не выиграете, за исключением того, что кешированная версия изображения будет висеть поблизости и, вероятно, дольше, чем вам нужно. Однако, если у вас есть большое изображение, которое вам нужно часто перерисовывать, тогда есть альтернативы, хотя я бы рекомендовал в первую очередь избегать перерисовки этого большого изображения :).
Что касается общего поведения кеша, он выполняет кеширование на основе имени файла (поэтому два экземпляра + imageNamed: с тем же именем должны приводить к ссылкам на одни и те же кешированные данные), и кеш будет динамически расти, когда вы запрашиваете больше изображений через + imageNamed :. В iPhone OS 2.xa ошибка предотвращает сжатие кеша при получении предупреждения о памяти.
и
Насколько я понимаю, кеш + 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]];
}
Ринсвинд также включил пример кода для создания вашей собственной оптимизированной версии. Я не вижу, чтобы оно того стоило, но вот оно для полноты картины.
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);
Компромисс с этим кодом заключается в том, что декодированное изображение использует больше памяти, но рендеринг происходит быстрее.