tldr : ImagedNamed는 괜찮습니다. 메모리를 잘 처리합니다. 그것을 사용하고 걱정하지 마십시오.
2012 년 11 월 편집 :이 질문은 iOS 2.0에서 시작되었습니다. 그 이후로 이미지 요구 사항과 처리가 많이 바뀌 었습니다. Retina는 이미지를 더 크게 만들고 로딩을 약간 더 복잡하게 만듭니다. iPad 및 레티 나 이미지에 대한 지원이 내장되어 있으므로 코드에서 ImageNamed를 사용해야합니다. 이제 후세를 위해 :
Apple Dev Forums 의 자매 스레드 는 더 나은 트래픽을 받았습니다. 특히 Rincewind 는 권한을 추가했습니다.
iPhone OS 2.x에는 메모리 경고 후에도 imageNamed : 캐시가 지워지지 않는 문제가 있습니다. 동시에 + imageNamed : 캐시가 아니라 편의를 위해 많이 사용되었습니다. 이로 인해 문제가 예상했던 것보다 더 확대되었을 것입니다.
경고하면서
속도면에서 무슨 일이 일어나고 있는지에 대한 일반적인 오해가 있습니다. + imageNamed :가 수행하는 가장 큰 일은 소스 파일에서 이미지 데이터를 디코딩하는 것입니다.이 경우 거의 항상 데이터 크기가 크게 증가합니다 (예 : 화면 크기의 PNG 파일은 압축 할 때 수십 KB를 소비하지만 절반 MB 이상을 소비합니다. 압축 해제-너비 * 높이 * 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]];
}
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);
이 코드의 단점은 디코딩 된 이미지가 더 많은 메모리를 사용하지만 렌더링이 더 빠르다는 것입니다.