it-swarm.com.de

Unterschied zwischen [UIImage imageNamed ...] und [UIImage imageWithData ...]?

Ich möchte einige Bilder aus dem Dateisystem in meine Anwendung laden. Es gibt zwei einfache Möglichkeiten, dies zu tun:

[UIImage imageNamed:fullFileName]

oder:

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

[UIImage imageWithData:imageData];

Ich bevorzuge den ersten, weil er viel weniger Code enthält, aber ich habe einige Leute gesehen, die sagten, dass das Bild zwischengespeichert wird und dass diese Methode mehr Speicher benötigt. Da ich den Leuten in den meisten anderen Foren nicht vertraue, dachte ich, ich würde die Frage hier stellen, gibt es einen praktischen Unterschied und wenn ja, welcher ist "besser"?

Ich habe versucht, meine App mit dem Object-Allocation-Instrument zu profilieren, und ich sehe keinen praktischen Unterschied, obwohl ich es nur im Simulator und nicht auf einem iPhone selbst versucht habe.

64
rustyshelf

Es hängt davon ab, was Sie mit dem Bild machen. Die imageNamed:-Methode speichert das Bild zwar zwischenspeichern, dies hilft jedoch in vielen Fällen bei der Speichernutzung. Wenn Sie beispielsweise ein Bild zehnmal laden, um zusammen mit Text in einer Tabellenansicht angezeigt zu werden, speichert UIImage nur eine einzelne Darstellung dieses Bildes im Speicher, anstatt zehn separate Objekte zuzuordnen. Wenn Sie jedoch ein sehr großes Bild haben und es nicht erneut verwenden, möchten Sie das Bild möglicherweise aus einem Datenobjekt laden, um sicherzustellen, dass es aus dem Speicher entfernt wird, wenn Sie fertig sind.

Wenn Sie keine großen Bilder haben, würde ich mir keine Sorgen machen. Wenn Sie kein Problem sehen (und Kudos für die Überprüfung der Objektzuordnung anstelle der präventiven Optimierung), würde ich weniger Codezeilen als vernachlässigbare Arbeitsspeicherverbesserungen wählen.

90

Nach meiner Erfahrung hat [UIImage imageNamed:] eine erheblich bessere Leistung, insbesondere wenn es in UITableViews verwendet wird.

Es ist nicht nur der Speicher, sondern auch das Dekodieren von image. Das Cachen ist viel schneller.

10
Hunter

Wie die API-Referenz von UIImage sagt:

+ (UIImage *) imageNamed: (NSString *) name

Diese Methode sucht in den Systemcaches nach einem Bildobjekt mit dem angegebenen Namen und gibt dieses Objekt zurück, wenn es existiert. Wenn sich noch kein passendes Bildobjekt im Cache befindet, lädt diese Methode die Bilddaten aus der angegebenen Datei, speichert sie im Cache und gibt das resultierende Objekt zurück.

+ (UIImage *) imageWithContentsOfFile: (NSString *) Pfad

Diese Methode speichert das Bildobjekt nicht zwischen.

wenn Sie also viele UI-Elemente (z. B. UITableViewCell) haben, die möglicherweise dasselbe Bild verwenden (häufig als icons), ist dies aus Performance-Gründen natürlich erwünscht Verwenden Sie das dasselbe Bild erneut, um Speicherplatz für andere Zwecke zu speichern. Generell wird das wiederverwendete Bild häufig in dem UI-Element verwendet, das unser Benutzer damit bearbeiten kann viele Male. Es legt also Wert darauf, dass es wiederverwendet wird. Sie können also die imageNamed -Methode verwenden.

Auf der anderen Seite wird es in einer Anwendung ein UI-Element geben, das während des Lebenszyklus der App vorhanden ist, beispielsweise ein Button oder eine Logo-Ansicht. Diese von diesen UI-Elementen verwendeten Bilder können ebenfalls verwendet werden Während des gesamten Lebenszyklus der App würden Sie nicht darüber nachdenken, ob diese Images im Cache gespeichert werden sollen oder nicht. Sie können also die Methode imageNamed wählen.


Im Gegenteil, in einer Anwendung gibt es häufig einige UI-Elemente, die dynamisch erstellt werden. Unsere Anwendung unterstützt beispielsweise dynamisches background, sodass Benutzer den gewünschten Hintergrund auswählen können. Und background kann ein Bild sein. So haben wir möglicherweise eine Schnittstelle, die viele verschiedene background auflistet. ] (häufig durch Verwendung von UIImageView anzeigen). Zur Auswahl des Benutzers können wir die Listenansicht MyBackgroundListView nennen. Wenn der Benutzer einen Hintergrund image auswählt, sollte die MyBackgroundListView angezeigt werden zerstört, da seine Funktion beendet ist. Wenn der Benutzer das nächste Mal seinen/ihren Hintergrund ändern möchte, können wir MyBackgroundListView erneut erstellen. Die images, die von MyBackgroundListView verwendet werden, sollten daher nicht sein zwischengespeichert, oder der Speicher unserer Anwendung wird knapp. Daher sollten Sie die Methode imageWithContentsOfFile verwenden.

Wie das Apple-Dokument Hochauflösende Bildschirme in Ansichten unterstützt sagt

Bei Geräten mit hochauflösenden Bildschirmen sucht die Methode imageNamed:, imageWithContentsOfFile: und initWithContentsOfFile: automatisch nach einer Version des angeforderten Images mit dem @ 2x-Modifikator im Namen. Wenn es eines findet, lädt es stattdessen das Bild. Wenn Sie für ein bestimmtes Bild keine hochauflösende Version bereitstellen, lädt das Bildobjekt trotzdem ein Bild mit Standardauflösung (sofern vorhanden) und skaliert es während des Zeichnens.

sie müssen sich also um den Suchpfad des Bildes für das Problem der Netzhaut kümmern. IOS wird Ihnen helfen, damit umzugehen.

Tut mir leid für mein schlechtes Englisch . Möge es hilfreich sein.

9
monjer

Wenn Sie nicht möchten, dass Ihr Image zwischengespeichert wird, können Sie initWithContentsOfFile auch direkt verwenden: 

NSString *fileLocation = [[NSBundle mainBundle] pathForResource:fileName ofType:extension];
UIImage* yourImage = [[[UIImage alloc] initWithContentsOfFile:imagePath] autorelease];
7
CedricSoubrie

Mir wurde auch gesagt, dass [UIImage imageNamed:] ein wenig zu viel Zwischenspeicherung vornimmt und Bilder nicht oft veröffentlicht werden. Mir wurde gesagt, ich solle vorsichtig damit umgehen.

5
Ben Gottlieb

imageWithData ist nützlich, wenn Sie ein binäres Bild in einer Datenbank speichern oder ein großes Bild schrittweise aus dem Web herunterladen.

3
Dan

Ich würde imagenamed nicht verwenden, wenn Ihre App viele große Bilder enthält, die nicht gleich sind. Ich habe einen App-Absturz erlebt, weil ich zu viel davon verwendet habe.

0
user281300