Um den Zweck dieser Frage zu klären: Ich weiß, wie man komplizierte Ansichten mit beiden Unteransichten und mit drawRect erstellt. Ich versuche zu verstehen, wann und warum man übereinander verwendet.
Ich verstehe auch, dass es keinen Sinn macht, so viel im Voraus zu optimieren und etwas schwieriger zu machen, bevor Sie ein Profiling durchführen. Bedenken Sie, dass ich mit beiden Methoden vertraut bin und jetzt wirklich ein tieferes Verständnis möchte.
Ein großer Teil meiner Verwirrung ist darauf zurückzuführen, dass ich gelernt habe, wie man die Bildlaufleistung in der Tabellenansicht wirklich reibungslos und schnell macht. Natürlich stammt die ursprüngliche Quelle dieser Methode vom Autor hinter Twitter für iPhone (ehemals Tweetie). Grundsätzlich heißt es, dass das Geheimnis darin besteht, KEINE Unteransichten zu verwenden, um das Scrollen von Tabellen reibungslos zu gestalten, sondern die gesamte Zeichnung in einer benutzerdefinierten Ansicht zu erstellen. Im Wesentlichen scheint es, dass die Verwendung vieler Unteransichten das Rendern verlangsamt, da sie viel Overhead haben und ständig über ihren übergeordneten Ansichten neu zusammengesetzt werden.
Um fair zu sein, wurde dies geschrieben, als das 3GS ziemlich brandneu war und iDevices seitdem viel schneller geworden sind. Noch diese Methode wird regelmäßig vorgeschlagen auf den interwebs und anderswo für Hochleistungstabellen. Tatsächlich ist es eine empfohlene Methode in Apples Tabellenbeispielcode , die in mehreren WWDC-Videos ( Praktisches Zeichnen für iOS-Entwickler ) und vielen iOS- Programmierbüchern vorgeschlagen wurde .
Es gibt sogar fantastisch aussehende Tools , um Grafiken zu entwerfen und Core Graphics-Code für sie zu generieren.
Zuerst muss ich glauben: "Es gibt einen Grund, warum Core Graphics existiert. Es ist SCHNELL!"
Sobald ich jedoch auf die Idee komme, "Core Graphics nach Möglichkeit zu bevorzugen", stelle ich fest, dass drawRect häufig für eine schlechte Reaktionsfähigkeit in einer App verantwortlich ist, extrem teuer im Speicher ist und die CPU wirklich belastet. Grundsätzlich sollte ich vermeiden, drawRect zu überschreiben (WWDC 2012 iOS App Performance: Grafiken und Animationen )
Ich denke, wie alles ist es kompliziert. Vielleicht können Sie mir und anderen helfen, das Wann und Warum für die Verwendung von drawRect zu verstehen?
Ich sehe einige offensichtliche Situationen bei der Verwendung von Core Graphics:
- Sie haben dynamische Daten (Apple Stock Chart Beispiel)
- Sie haben ein flexibles UI-Element, das nicht mit einem einfachen Bild mit veränderbarer Größe ausgeführt werden kann
- Sie erstellen eine dynamische Grafik, die nach dem Rendern an mehreren Stellen verwendet wird
Ich sehe Situationen, um Core Graphics zu vermeiden:
- Die Eigenschaften Ihrer Ansicht müssen separat animiert werden
- Sie haben eine relativ kleine Ansichtshierarchie, sodass sich ein wahrgenommener zusätzlicher Aufwand bei der Verwendung von CG nicht lohnt
- Sie möchten Teile der Ansicht aktualisieren, ohne das Ganze neu zu zeichnen
- Das Layout Ihrer Unteransichten muss aktualisiert werden, wenn sich die Größe der übergeordneten Ansicht ändert
Geben Sie also Ihr Wissen. In welchen Situationen greifen Sie nach drawRect / Core Graphics (dies könnte auch mit Unteransichten erreicht werden)? Welche Faktoren führen Sie zu dieser Entscheidung? Wie / Warum wird das Zeichnen in einer benutzerdefinierten Ansicht für das Scrollen mit butterweichen Tabellenzellen empfohlen, Apple rät jedoch aus Leistungsgründen generell von drawRect ab? Was ist mit einfachen Hintergrundbildern (wann erstellen Sie sie mit CG oder mit einem anpassbaren PNG-Bild)?
Ein tiefes Verständnis dieses Themas ist möglicherweise nicht erforderlich, um lohnende Apps zu erstellen, aber ich mag es nicht, zwischen Techniken zu wählen, ohne erklären zu können, warum. Mein Gehirn wird sauer auf mich.
Frage Update
Vielen Dank für die Informationen an alle. Einige klärende Fragen hier:
- Wenn Sie etwas mit Kerngrafiken zeichnen, aber mit UIImageViews und einem vorgerenderten PNG dasselbe erreichen können, sollten Sie immer diesen Weg gehen?
- Eine ähnliche Frage: Wann sollten Sie vor allem bei Badass-Tools wie diesen in Betracht ziehen, Oberflächenelemente in Kerngrafiken zu zeichnen? (Wahrscheinlich, wenn die Anzeige Ihres Elements variabel ist. ZB eine Schaltfläche mit 20 verschiedenen Farbvarianten. Andere Fälle?)
- Könnten nach meinem Verständnis in meiner Antwort unten möglicherweise die gleichen Leistungssteigerungen für eine Tabellenzelle erzielt werden, indem eine Snapshot-Bitmap Ihrer Zelle nach dem Rendern Ihres komplexen UIView-Renderings effektiv erfasst und beim Scrollen und Ausblenden Ihrer komplexen Ansicht angezeigt wird? Offensichtlich müssten einige Stücke ausgearbeitet werden. Nur ein interessanter Gedanke, den ich hatte.
quelle
Ich werde versuchen, eine Zusammenfassung dessen zu erstellen, was ich aus den Antworten anderer hier extrapoliere, und in einem Update der ursprünglichen Frage klärende Fragen stellen. Aber ich ermutige andere, immer wieder Antworten zu geben und diejenigen abzustimmen, die gute Informationen geliefert haben.
Allgemeiner Ansatz
Es ist ziemlich klar, dass der allgemeine Ansatz, wie Ben Sandofsky in seiner Antwort erwähnte , lauten sollte: "Wann immer Sie können, verwenden Sie UIKit. Führen Sie die einfachste Implementierung durch, die funktioniert. Profil. Wenn es einen Anreiz gibt, optimieren Sie."
Das Warum
Durch das Zeichnen von Zelleninhalten in einer flachen UIView können Sie Ihre FPS beim Scrollen von Tabellen erheblich verbessern.
Wie ich oben sagte, sind CPU und GPU zwei mögliche Engpässe. Da sie im Allgemeinen unterschiedliche Dinge behandeln, müssen Sie darauf achten, auf welchen Engpass Sie stoßen.Beim Scrollen von Tabellen ist es nicht so, dass Core Graphics schneller zeichnet, und deshalb kann es Ihre FPS erheblich verbessern.
Tatsächlich ist Core Graphics möglicherweise sehr langsam langsamer als eine verschachtelte UIView-Hierarchie für das anfängliche Rendern. Es scheint jedoch, dass der typische Grund für abgehacktes Scrollen darin besteht, dass Sie einen Engpass bei der GPU haben. Daher müssen Sie dies beheben.
Warum das Überschreiben von drawRect (unter Verwendung von Kerngrafiken) das Scrollen von Tabellen erleichtern kann:
Soweit ich weiß, ist die GPU nicht für das anfängliche Rendern der Ansichten verantwortlich, sondern erhält stattdessen Texturen oder Bitmaps, manchmal mit einigen Ebeneneigenschaften, nachdem sie gerendert wurden. Es ist dann für das Zusammensetzen der Bitmaps, das Rendern all dieser Ebeneneffekte und den Großteil der Animation (Kernanimation) verantwortlich.
Bei Zellen mit Tabellenansicht kann die GPU mit komplexen Ansichtshierarchien einen Engpass aufweisen, da anstelle der Animation einer Bitmap die übergeordnete Ansicht animiert und Berechnungen des Unteransichtslayouts durchgeführt, Ebeneneffekte gerendert und alle Unteransichten zusammengesetzt werden. Anstatt eine Bitmap zu animieren, ist sie für die Beziehung zwischen mehreren Bitmaps und deren Interaktion für denselben Pixelbereich verantwortlich.
Zusammenfassend lässt sich sagen, dass der Grund, warum das Zeichnen Ihrer Zelle in einer Ansicht mit Kerngrafiken das Scrollen in der Tabelle beschleunigen kann, NICHT darin besteht, dass das Zeichnen schneller erfolgt, sondern dass die GPU entlastet wird. Dies ist der Engpass, der Ihnen in diesem bestimmten Szenario Probleme bereitet .
quelle
Ich bin ein Spieleentwickler und habe die gleichen Fragen gestellt, als mein Freund mir sagte, dass meine UIImageView-basierte Ansichtshierarchie mein Spiel verlangsamen und es schrecklich machen würde. Anschließend recherchierte ich alles, was ich über die Verwendung von UIViews, CoreGraphics, OpenGL oder einem Drittanbieter wie Cocos2D finden konnte. Die konsequente Antwort, die ich von Freunden, Lehrern und Apple-Ingenieuren bei WWDC erhielt, war, dass es am Ende keinen großen Unterschied geben wird, weil sie auf einer bestimmten Ebene alle dasselbe tun . Optionen auf höherer Ebene wie UIViews basieren auf Optionen auf niedrigerer Ebene wie CoreGraphics und OpenGL. Sie sind lediglich in Code eingeschlossen, um Ihnen die Verwendung zu erleichtern.
Verwenden Sie CoreGraphics nicht, wenn Sie die UIView nur neu schreiben möchten. Durch die Verwendung von CoreGraphics können Sie jedoch etwas an Geschwindigkeit gewinnen, solange Sie alle Zeichnungen in einer Ansicht ausführen. Dies lohnt sich jedoch wirklich es sich ? Die Antwort, die ich gefunden habe, ist normalerweise nein. Als ich mein Spiel zum ersten Mal startete, arbeitete ich mit dem iPhone 3G. Als mein Spiel immer komplexer wurde, bemerkte ich einige Verzögerungen, aber bei den neueren Geräten war dies völlig unbemerkt. Jetzt ist viel los und die einzige Verzögerung scheint ein Rückgang von 1-3 fps zu sein, wenn ich auf einem iPhone 4 im komplexesten Level spiele.
Trotzdem entschied ich mich, Instrumente zu verwenden, um die Funktionen zu finden, die am meisten Zeit in Anspruch nahmen. Ich stellte fest, dass die Probleme nicht mit meiner Verwendung von UIViews zusammenhängen . Stattdessen wurde CGRectMake wiederholt für bestimmte Kollisionserkennungsberechnungen aufgerufen und Bild- und Audiodateien für bestimmte Klassen, die dieselben Bilder verwenden, separat geladen, anstatt sie aus einer zentralen Speicherklasse ziehen zu lassen.
Am Ende können Sie vielleicht einen leichten Gewinn mit CoreGraphics erzielen, aber normalerweise lohnt es sich nicht oder hat überhaupt keine Wirkung. Ich verwende CoreGraphics nur, wenn ich geometrische Formen anstelle von Text und Bildern zeichne.
quelle