이름이 지정된 UI 이미지 제거: FUD
2014년 2월 편집: 이 질문은 iOS 2.0부터 시작되었습니다! 그 이후로 이미지 요구 사항과 처리가 많이 바뀌었습니다.Retina는 이미지를 더 크게 만들고 로드를 약간 더 복잡하게 만듭니다.iPad 및 레티나 이미지에 대한 내장 지원을 사용하면 코드에 ImageNamed를 사용해야 합니다.
저는 많은 사람들이 말하는 것을 봅니다.imageNamed나쁘지만 성능이 좋다고 말하는 사람들의 수는 같습니다 - 특히 렌더링 시UITableView예를 들어 이 SO 질문이나 iPhoneDeveloperTips.com 의 이 기사를 참조하십시오.
UIImage의imageNamed누출을 방지하기 위해 사용되는 방법이지만 최근 릴리스에서는 수정되었습니다.캐시 알고리즘을 더 잘 이해하여 이미지를 캐시하는 시스템을 신뢰할 수 있는 위치와 추가 작업을 수행해야 하는 위치에 대한 합리적인 결정을 내리고 싶습니다.현재 제 기본적인 이해는 단순하다는 것입니다.NSMutableDictionaryUIImages파일 이름으로 참조됩니다.그것은 점점 커지고 메모리가 부족해지면 훨씬 더 작아집니다.
예를 들어, 이미지 캐시가 뒤에 있는지 확실히 아는 사람이 있습니까?imageNamed응하지에 .didReceiveMemoryWarning애플이 이것을 하지 않을 것 같지는 않습니다.
캐싱 알고리즘에 대한 통찰력이 있으면 여기에 게시하십시오.
tldr: ImageNamed는 괜찮습니다.그것은 기억력을 잘 처리합니다.그것을 사용하고 걱정하지 마세요.
2012년 11월 편집: 이 질문은 iOS 2.0부터 시작되었습니다! 그 이후로 이미지 요구 사항과 처리가 많이 바뀌었습니다.Retina는 이미지를 더 크게 만들고 로드를 약간 더 복잡하게 만듭니다.iPad 및 레티나 이미지에 대한 내장 지원을 사용하면 코드에 ImageNamed를 사용해야 합니다.이제, 후세를 위하여:
Apple Dev Forum의 자매 스레드가 더 나은 트래픽을 수신했습니다.특히 린스윈드는 약간의 권한을 추가했습니다.
iPhone OS 2.x에는 메모리 경고 후에도 이미지 Named: 캐시가 지워지지 않는 문제가 있습니다.이와 동시에 +imageNamed: 캐시가 아니라 편의성을 위해 많이 사용되었으며, 이로 인해 문제가 예상보다 더 크게 확대되었을 수 있습니다.
라고 경고하는 한편
스피드 전선에서는 무슨 일이 일어나고 있는지에 대한 일반적인 오해가 있습니다.+imageNamed:가 수행하는 가장 큰 작업은 소스 파일에서 이미지 데이터를 디코딩하는 것입니다. 이는 거의 항상 데이터 크기를 크게 부풀립니다(예: 화면 크기의 PNG 파일은 압축 시 수십 KB를 소비할 수 있지만 절반 이상의 압축 해제된 너비 * 높이 * 4).대조적으로 + 이미지WithContentsOfFile: 이미지 데이터가 필요할 때마다 해당 이미지의 압축을 해제합니다.상상할 수 있듯이 이미지 데이터가 한 번만 필요하면 캐시된 이미지 버전이 필요 이상으로 오래 걸리는 것을 제외하고는 아무것도 얻지 못했습니다.그러나 큰 이미지를 자주 다시 그려야 하는 경우에는 다른 방법이 있지만, 주로 큰 이미지를 다시 그려야 하는 것을 피하는 것이 좋습니다. :).
캐시의 일반적인 동작과 관련하여 파일 이름을 기반으로 캐시를 수행합니다(따라서 +imageNamed: 이름이 같은 두 인스턴스는 동일한 캐시 데이터에 대한 참조를 생성해야 함). +imageNamed:를 통해 더 많은 이미지를 요청하면 캐시가 동적으로 증가합니다.iPhone OS 2.x에서 버그는 메모리 경고가 수신될 때 캐시가 축소되는 것을 방지합니다.
그리고.
제가 알기로는 +imageNamed: 캐시는 iPhone OS 3.0의 메모리 경고를 존중해야 합니다.기회가 있을 때 테스트하고 그렇지 않은 경우 버그를 보고하십시오.
여기 있습니다. 이미지 이름: 창문을 부수거나 자녀를 살해하지 않습니다.이것은 매우 간단하지만 최적화 도구입니다.슬프게도 그것은 잘못된 이름이고 사용하기 쉬운 동등한 것은 없습니다. 그래서 사람들은 그것을 과도하게 사용하고 단순히 그것이 제 역할을 할 때 화가 납니다.
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);
이 코드의 단점은 디코딩된 이미지가 더 많은 메모리를 사용하지만 렌더링이 더 빠르다는 것입니다.
제 경험으로는 imageNamed에 의해 생성된 이미지 캐시가 메모리 경고에 응답하지 않습니다.저는 두 개의 애플리케이션을 가지고 있었는데, 그 애플리케이션들은 메모리 관리까지 가능한 한 희박했지만, 여전히 메모리 부족으로 인해 설명할 수 없을 정도로 손상되었습니다.imageNamed를 사용하여 이미지를 로드하는 것을 중단하자 두 애플리케이션 모두 훨씬 안정적으로 작동했습니다.
두 응용 프로그램 모두 다소 큰 이미지를 로드했지만 전혀 일반적이지 않은 것은 없었습니다.첫 번째 애플리케이션에서는 사용자가 동일한 이미지로 두 번 돌아올 가능성이 낮았기 때문에 캐싱을 아예 건너뛰었습니다.두 번째는 UI 이미지를 NSMutableDictionary에 보관하고 메모리 경고를 받으면 내용을 플러시하는 등 매우 간단한 캐싱 클래스를 구축했습니다.imageNamed:이(가) 그렇게 캐시했다면 성능 업그레이드를 보지 말았어야 했습니다.이 모든 것이 2.2에서 실행되었습니다. 3.0의 영향이 있는지 모르겠습니다.
첫 번째 앱에서 이 문제와 관련된 다른 질문을 찾을 수 있습니다. UI 이미지 캐시에 대한 StackOverflow 질문입니다.
다른 참고 사항 중 하나 - Interface Builder는 표지 아래에 Nameed 이미지를 사용합니다.이 문제가 발생할 경우 주의해야 할 사항입니다.
언급URL : https://stackoverflow.com/questions/924740/dispelling-the-uiimage-imagenamed-fud
'programing' 카테고리의 다른 글
| XML 파일을 R 데이터 프레임으로 구문 분석하는 방법은 무엇입니까? (0) | 2023.06.09 |
|---|---|
| 경로의 일부를 찾을 수 없습니다... bin\roslin\csc.exe (0) | 2023.06.04 |
| MySQL/MariaDB: 피벗 테이블 보기 만들기 (0) | 2023.06.04 |
| 각도에서 ngDefaultControl이란 무엇입니까? (0) | 2023.06.04 |
| XAML에는 디버그 모드에 대한 조건부 컴파일러 지시문이 있습니까? (0) | 2023.06.04 |