[Uİİmage imageNamed...] ve [Uİİmage imageWithData...] arasındaki fark?

ben dosya sisteminden benim uygulama içine bazı görüntüleri yüklemek istiyorum. Bunu yapmanın 2 kolay yolu var:

[UIImage imageNamed:fullFileName]

veya:

NSString *fileLocation = [[NSBundle mainBundle] pathForResource:fileName ofType:extension];
NSData *imageData = [NSData dataWithContentsOfFile:fileLocation];

[UIImage imageWithData:imageData];

ilkini tercih ediyorum çünkü çok daha az kod var, ancak bazı insanlar görüntünün önbelleğe alındığını ve bu yöntemin daha fazla bellek kullandığını söylüyor mu? Diğer birçok forumdaki insanlara güvenmediğimden beri, soruyu burada soracağımı düşündüm, pratik bir fark var mı ve eğer öyleyse hangisi daha iyi mi?

Uygulamamı nesne ayırma aletini kullanarak profillemeyi denedim ve sadece bir iPhone'da değil, simülatörde denemiş olsam da pratik bir fark göremiyorum.

64
tarihinde sordu Matthias Bauch 2008-11-25 05:53:28
kaynak

8 ответов

bu görüntü ile ne yaptığınızı bağlıdır. imageNamed: yöntemi görüntüyü önbelleğe alır, ancak çoğu durumda bellek kullanımına yardımcı olur. Örneğin, bir tablo görünümünde bazı metinlerle birlikte görüntülemek için bir görüntüyü 10 kez yüklerseniz, Uıımage yalnızca bu görüntünün tek bir gösterimini 10 ayrı nesne ayırmak yerine bellekte tutar. Öte yandan, çok büyük bir görüntünüz varsa ve yeniden kullanmıyorsanız, görüntüyü bir veriden yüklemek isteyebilirsiniz işiniz bittiğinde bellekten kaldırıldığından emin olmak için nesne.

herhangi bir büyük görüntü yoksa, ben bu konuda endişe olmaz. Bir sorun görmüyorsanız (ve preemptively optimize etmek yerine nesne tahsisini kontrol etmek için kudos), ihmal edilebilir bellek iyileştirmeleri üzerinde daha az kod satırı seçerim.

90
cevap Marc Charbonneau 2008-11-25 06:09:26
kaynak

deneyimimde [UIImage imageNamed:] , özellikle UITableViews de kullanıldığında daha iyi bir performansa sahiptir .

sadece bellek değil, aynı zamanda image kod çözme . Önbelleğe alınmış olması çok daha hızlıdır.

10
cevap Hunter 2013-06-06 16:39:34
kaynak

API referans olarak Uıımage diyor ki:

+(Uıımage *)ımagenamed:(NSString *)adı

bu yöntem, belirtilen ada sahip bir görüntü nesnesi için sistem önbelleklerini arar ve varsa bu nesneyi döndürür. Eşleşen bir görüntü nesnesi önbellekte zaten değilse, bu yöntem belirtilen dosyadan görüntü verilerini yükler, önbelleğe alır ve sonra ortaya çıkan döndürür nesne.

+(Uıımage *)ımagewithcontentsoffile:(NSString *)yol

bu yöntem görüntü nesnesini önbelleğe almaz.

yani, aynı UI öğeleri (örneğin uıtableviewcell gibi) aynı görüntü(genellikle bir simgeleri olarak) kullanabilir ve performans nedeniyle,tabii ki aynı görüntüyü yeniden kullanmak istiyorum , böylece diğer kullanım için biraz bellek kaydedeceğiz . Genel olarak yeniden kullanılan görüntü , kullanıcılarımızın çok sayıda kez üzerinde çalışabileceği uı öğesinde sıklıkla kullanılır . Bu yüzden yeniden kullanmak bizim için değer veriyor .Böylece ımagenamed yöntemini kullanmayı seçebilirsiniz .

ve diğer taraftan, bir uygulamada, uygulamanın ömrü boyunca orada olacak bazı UI öğesi olacak bir düğme,bir logo görünümü gibi döngü , bu nedenle bu uı öğeleri tarafından kullanılan bu görüntüler de uygulamanın yaşam döngüsü sırasında orada olabilir, bu görüntünün önbellek olup olmadığını düşünmezsiniz .Böylece ımagenamed yöntemini kullanmayı seçebilirsiniz .


aksine,bir uygulamada , genellikle dinamik olarak oluşturulan bazı UI öğeleri vardır. Örneğin, bizim uygulama desteği dinamik arka plan , böylece kullanıcı istedikleri arka planı seçebilir .Ve arka plan bir görüntü olabilir .Bu yüzden farklı arka plan (genellikle kullanım Uıımageview tarafından göstermek) çok listeleyen bir arayüz olabilir kullanıcı seçmek için, biz liste görünümü mybackgroundlistview adlandırabilirsiniz .Kullanıcı bir arka plan görüntü , seçtiğinde yani Mybackgroundlistview yok edilmelidir, çünkü işlevini sonlandırır.Kullanıcı arka planını değiştirmek istediğinde, MyBackgroundListView tekrar oluşturabiliriz .Yani görüntüleri tarafından kullanılan MyBackgroundListView önbelleğe olmamalıdır, ya da bizim uygulamanın bellek tükendi.Yani bu sefer kullanmanız gerekir ımagewithcontentsoffile yöntemi.

olarak Apple'ın doc görünümlerinde Yüksek Çözünürlüklü ekranları destekleyen diyor

Yüksek çözünürlüklü ekranlara sahip cihazlarda

, imageNamed: , imageWithContentsOfFile: ve initWithContentsOfFile: yöntemleri, istenen görüntünün @2x değiştiricisiyle otomatik olarak bir sürümünü arar. Bir bulursa, bunun yerine bu görüntüyü yükler. Sizi hızlı bir şekilde bulamadık! belirli bir görüntünün yüksek çözünürlüklü sürümü, görüntü nesnesi hala standart çözünürlüklü bir görüntü yükler (varsa) ve çizim sırasında ölçekler.

böylece Retina Ekran sorunu için görüntünün arama yolu hakkında endişe ediyorum . İOS bununla başa çıkmanıza yardımcı olacaktır.

zavallı İngilizcem için üzgünüm . Yardımcı olabilir.

9
cevap monjer 2013-08-19 18:37:28
kaynak

görüntünüzün önbelleğe alınmasını istemiyorsanız, doğrudan initwithcontentsoffile kullanabilirsiniz:

NSString *fileLocation = [[NSBundle mainBundle] pathForResource:fileName ofType:extension];
UIImage* yourImage = [[[UIImage alloc] initWithContentsOfFile:imagePath] autorelease];
7
cevap CedricSoubrie 2011-08-22 12:40:18
kaynak

ben de [UIImage imageNamed:] biraz fazla önbelleğe alma yapar ve görüntüler genellikle serbest değil söylendi. Kullanma konusunda dikkatli olmam söylendi.

5
cevap Ben Gottlieb 2008-11-25 06:19:18
kaynak

ımagewithdata, görüntü ikili dosyasını bir veritabanında saklarken veya Web'den büyük bir görüntü indirirken kullanışlıdır.

3
cevap Dan 2008-11-25 13:16:26
kaynak

uygulamanızın aynı olmayan büyük görüntülerin yükleri varsa ımagenamed kullanmazdım. Çok fazla kullandığım için uygulama çökmesini yaşadım.

0
cevap user281300 2010-11-25 01:53:24
kaynak

görüntünün önbelleğe alındığına inanmıyorum ve neden hepiniz bunu söylüyorsunuz bilmiyorum. Uıımage, ilgili şeyleri takip etmek için referans sayaçları kullanan NSObject alt sınıfıdır. Yani bir görüntü yüklediğinizde aynı şeyi yapar. Aynı görüntüyü birden çok kez yüklerseniz, görüntünün yalnızca bir kopyasına sahip olur (veya olmalıdır) ve bu görüntü ile bir şey kullanmak zorunda olduğunuz her seferinde referans sayacını artıracaktır. Referans Sayaçları I sayım 0'a ulaştığında kendisini siler. yani" alloc"," retain "saymak için her +1 ve" release " -1. Sadece belleği yönetmek için daha iyi bir yol değil, aynı zamanda bu programlama stili bellek sızıntılarını temizlemeye yardımcı olur.

-11
cevap andrew 2010-12-17 11:43:08
kaynak

Diğer sorular cocoa-touch iphone