2010-08-09 11 views
8

Hier ist der Code:Warum ist dieser CATiledLayer/PDF-Code langsam?

https://www.dropbox.com/s/o42wy36x4qhrbpt/PDFScroller.zip

Ich nahm die WWDC 2010 PhotoScroller Beispielcode, der für das Zoomen verschachtelte UIScrollViews implementiert, in einem UIScrollView für Paging und ausgelagert, was ich dachte wäre minimale Menge an Code erforderlich zum Anzeigen einer mehrseitigen PDF-Datei anstelle von Bildern.

Es funktioniert. Aber es ist langsam auf meinem iPhone4, ungefähr drei Sekunden, um die erste Seite zu malen, und noch langsamer auf meinem iPod Touch. Ich kann mir die einzelnen Fliesen ansehen. Das gleiche PDF öffnet sich bereits schneller, ohne sichtbare Kachelzeichnung, in einer alternativen CATiledLayer Implementierung, die einfach eine einzige verwendet und Ereignisse berühren, um Seiten zu wechseln. Ich würde gerne diese PhotoScroller Technik verwenden, es ist sehr nett.

Ich sah es mit CPU-Sampler in Instruments, und es scheint nicht der PDF-Rendering-Code zu sein, es sieht aus wie die Zeit in Threading und Messaging aufgenommen wird. Ich würde es schätzen, wenn jemand helfen könnte, aufzuzeigen, was dieses Beispiel tut, um den Overhead zu verursachen.

Danke,

Jim


Update 1: Früher habe ich ursprünglich hatte die TilingView Klasse Technik aus dem Beispielcode von

+ (Class) layerClass { 
    return [CATiledLayer class]; 
} 

zu definieren und dann in - (void)drawRect:(CGRect)rect Zeichnung aber umgeschaltet die explizite CATiledLayer Unterklasse als ein erster Versuch zu sehen, ob es einen Unterschied machen würde, aber es nicht, und Also habe ich den Code unverändert für die Veröffentlichung hier gelassen. Es gibt auch eine fehlende [tiledLayer release]; Leck in TilingView.

+0

Haben Sie es geschafft, eine Lösung dafür zu finden? Ich arbeitete an demselben. –

+0

Ja, eine Erhöhung der Kachelgröße verbessert die Leistung erheblich. – jbm

+0

Haben Sie es, nur eine neue Zeile im Code hinzugefügt: tiledLayer.tileSize = CGSizeMake (512, 512); Hat wirklich gut funktioniert! Vielen Dank. –

Antwort

2

Da Ihr Code einige Fehler enthält und ich den Code nicht kompilieren kann, habe ich mir die PDF-Datei angesehen, die im Archiv enthalten war, und ich weiß, warum Ihr TilingView langsam ist.

Normalerweise, wenn Sie eine pdf-Seite in einem CGContext mit der Methode CGContextDrawPDFPage: zeichnen, wurden alle Text- und Vektorgrafiken gerendert und andere Dinge wie normale Grafiken in der PDF werden nur gezogen und zwischengespeichert. Es spielt also keine Rolle, wie groß die PDF-Datei ist, aber es spielt eine Rolle, ob Sie vektorielle Grafiken in Ihrer PDF-Datei haben. Es scheint, dass Sie in Ihrem PDF eine vektorielle Grafik und einige mathematische Gleichungen haben, deshalb ist es langsam. Ich empfehle Ihnen, mit einer anderen PDF-Datei zu versuchen, die keine Vektorgrafiken enthält, und zu sehen, ob sie schneller ist. PDF ist ein Vektor-basiertes Format für die meisten Dokumente (mit Ausnahme derjenigen, die einfach dienen als Behälter für eingebettete TIFF-Bilder):

Prost

Zheng

+0

Zheng, danke für deine Antwort. Auf meinem Computer wird der Code mit dem neuesten iOS 4.0.2 SDK erstellt und ausgeführt. Und was den Inhalt der PDF-Datei betrifft, so kann ich leider nicht entscheiden, welches PDF meine Benutzer ansehen möchten. Ich muss einfach mein Bestes geben, um ein gültiges PDF-Dokument zu erstellen. – jbm

1

Conjecture mit jeder Art von Autorität werden nicht getroffen . Wenn Sie die PDF-Datei wie den PhotoScroller kacheln, bitten Sie das Telefon im Wesentlichen darum, die gesamte PDF-Datei (zumindest die angegebene Seite) für jede einzelne Kachel zu skalieren und zu rastern. Anstatt es für einen einzelnen CATiledLayer einmal zu malen, machst du es mehrmals für jede Auflösung. Da das PDF ein skalierbares Format für sich ist, sollten Sie in der Lage sein, die gesamte Ansicht für jede Seite/Skala einfach einmal zu rendern.

Update: Nachdem ich dies selbst durchgemacht habe, hat das PhotoScroller-Beispiel einige logische Probleme, die es sehr langsam machen. Im Grunde wird jede Kachel auf 1/zoomScale gerendert und die Skalierung wird wieder auf zoomScale zurückgesetzt. Also, wenn der Zoom bei .5 ist, rendert es bei 2x und skaliert das dann wieder auf 0,5x herunter. Sehr langsam und ineffizient.

+1

Einverstanden, und der CATiledLayer sollte sich darum kümmern, oder? Es wäre schön, eine Diagnoseausgabe oder sogar eine Delegate-API aus dieser Klasse zu haben, um uns mitzuteilen, wie sich das Caching verhält, je nach den von uns festgelegten Eigenschaften: Kachelgröße, Detail, Detailverzerrung. Ich nehme an, sie brauchen Raum, um den Algorithmus zu optimieren. – jbm