tldr: ImagedNamed iyidir. Hafızayı iyi idare eder. Kullan ve endişelenmeyi bırak.
Kasım 2012'yi Düzenle : Bu sorunun iOS 2.0'dan kalma olduğunu unutmayın! Görüntü gereksinimleri ve kullanımı o zamandan beri çok değişti. Retina, görüntüleri büyütür ve biraz daha karmaşık hale getirir. İPad ve retina görüntüleri için yerleşik destekle, kodunuzda kesinlikle ImageNamed kullanmalısınız. Şimdi, gelecek nesillerin aşkına:
Kardeş parçacığı Apple Dev Forumlar bazı iyi trafik almış. Özellikle Rincewind biraz yetki ekledi.
İPhone OS 2.x'te, bir bellek uyarısından sonra bile imageNamed: önbelleğin temizlenemeyeceği sorunlar var. Aynı zamanda + imageNamed: önbellek için değil, kolaylık sağlamak için çokça kullanıldı, bu da sorunu olması gerekenden daha fazla büyüttü.
uyarırken
Hız cephesinde, neler olduğuna dair genel bir yanlış anlama var. + İmageNamed'in yaptığı en büyük şey, kaynak dosyadaki görüntü verilerinin kodunu çözmektir; bu, neredeyse her zaman veri boyutunu önemli ölçüde artırır (örneğin, ekran boyutundaki bir PNG dosyası sıkıştırıldığında birkaç düzine KB tüketebilir, ancak yarım MB'den fazla tüketir. sıkıştırılmış - genişlik * yükseklik * 4). Buna karşılık + imageWithContentsOfFile: görüntü verilerine her ihtiyaç duyulduğunda bu görüntüyü açar. Tahmin edebileceğiniz gibi, görüntü verilerine yalnızca bir kez ihtiyacınız varsa, burada görüntünün önbelleğe alınmış bir sürümünün etrafta asılı kalması ve muhtemelen ihtiyacınız olandan daha uzun süre olması dışında hiçbir şey kazanamazsınız. Bununla birlikte, sık sık yeniden çizmeniz gereken büyük bir resminiz varsa, alternatifler de vardır, ancak öncelikle tavsiye edeceğim şey o büyük resmi yeniden çizmekten kaçınmaktır :).
Önbelleğin genel davranışıyla ilgili olarak, dosya adına göre önbelleğe alır (bu nedenle, aynı ada sahip iki + imageNamed örneği, aynı önbelleğe alınmış verilere başvurularla sonuçlanmalıdır) ve önbellek, aracılığıyla daha fazla görüntü talep ettikçe dinamik olarak büyür. + imageNamed :. İPhone OS 2.xa bug, bir bellek uyarısı alındığında önbelleğin küçülmesini engeller.
ve
Anladığım kadarıyla + imageNamed: önbelleğin iPhone OS 3.0'daki bellek uyarılarına uyması gerekiyor. Şansınız olduğunda test edin ve durumun böyle olmadığını anlarsanız hataları bildirin.
İşte orada var. imageNamed: camlarınızı kırmaz veya çocuklarınızı öldürmez. Oldukça basit ama bir optimizasyon aracı. Ne yazık ki kötü bir şekilde adlandırılmış ve kullanımı kolay bir muadili yok - bu yüzden insanlar onu aşırı kullanıyor ve sadece işini yaptığında üzülüyor
Bunu düzeltmek için UIImage'a bir kategori ekledim:
// 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 ayrıca kendi optimize edilmiş sürümünüzü oluşturmak için bazı örnek kodlar içeriyordu. Bakıma değer olduğunu göremiyorum ama burada tamlık için.
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);
Bu kodla değiş tokuş, kodu çözülen görüntünün daha fazla bellek kullanması, ancak oluşturmanın daha hızlı olmasıdır.