2016-11-21 5 views
1

Ich habe eine Renderfunktion geschrieben, die jede 1/60 Sekunde aufgerufen wird. Es ist unten gezeigt. Im Wesentlichen werden 40 Linien in einem radialen Muster dargestellt, das Sinus verwendet. Es sieht so aus http://imgur.com/a/kPKtT. Wenn ich es auf meinem iPhone 6s mit dem Debugger starte, zeigt es, dass es ungefähr 60% der CPU verwendet und es macht nur den "hohen" Akkuverbrauch aus. Das scheint mir nicht richtig, es sind nur 40 einfache Zeilen oder?iOS CGContext Schlechte Leistung

Könnte ich das effizienter machen? Sollte ich versuchen, etwas anderes wie CALayer oder Metal für bessere Leistung zu verwenden? Ich bin übrigens ein Noob.

func render() { tick += 0.01 
    let renderer = UIGraphicsImageRenderer(size: CGSize(width: 375, height: 667)) 
    let img = renderer.image { ctx in 
     let c = ctx.cgContext 

     // Set background 
     let background = CGRect(x: 0, y: 0, width: 375, height: 667) 
     c.setFillColor(UIColor.black.cgColor) 
     c.addRect(background) 
     c.drawPath(using: .fillStroke) 

     // Function to draw a line 
     func line(p1:CGPoint, p2:CGPoint) { 
      let line = CGRect(x: 0, y: 0, width: 200, height: 200) 
      c.addLines(between: [p1,p2]) 
      c.drawPath(using: .fillStroke) 
     } 

     // Draw lines 
     c.setStrokeColor(UIColor.white.cgColor) 
     c.setLineWidth(1) 
     c.setLineCap(CGLineCap.round) 
     for i in 0...39 { 
      let n:CGFloat = CGFloat(i) * CGFloat.pi/40 
      let d:CGFloat = sin(tick + CGFloat(i)*CGFloat.pi/5)*20 + 100 
      line(p1: CGPoint(x: d*cos(tick+n)+187.5,   y: d*sin(tick+n)+333.5), 
       p2: CGPoint(x: d*cos(tick+n+CGFloat.pi)+187.5, y: d*sin(tick+n+CGFloat.pi)+333.5)) 
     } 
    } 
    imageView.image = img 
} 
+0

'while true {print ("loop"}' sollte schnell sein, es ist nur 1 Zeile, nicht wahr? – Alexander

+0

sollte wohl scenekit/GameKit oder openGL, dies zu tun, ich glaube nicht, UIGraphicsImageRenderer entworfen wurde verwendet werden Auf diese Weise – Fonix

+0

Sie cos 2400 mal pro Sekunde und sin 3600 mal pro Sekunde aufrufen sowie mindestens 16800 Multiplikationen pro Sekunde alle nur innerhalb der For-Schleife. – rmaddy

Antwort

1

Ich denke, Apptoach ist nicht gut. Wenn Sie animierten Inhalt anzeigen möchten, sollten Sie keine Ansichten neu zeichnen. Sie sollten CoreAnimation verwenden. Die gute Nachricht ist einfach zu implementieren. Die schlechte Nachricht ist, dass es ein bisschen zu lernen braucht. ;)

Einige Vorschläge, um Ihren Code:

  1. Einige Teile Ihrer Zeichnung scheint konstant zu sein. Also sollte das nicht immer wieder neu gezeichnet werden. Stattdessen können Sie es in eine separate Ebene einfügen.
  2. Als @rmaddy schlägt vor, dass Sie viele sin und cos Berechnungen benötigen. Aber diese Werte sollten immer gleich sein. Sie können sie also einmal berechnen und zwischenspeichern.
  3. Sie können die Zeichnung in draw(in:) implementieren und dynamische Eigenschaften für alle variablen Teile den Code verwenden. Sie können Animationen von CoreAnimation verwenden, um Ihre Zeichnung zu animieren. Das Erstellen dynamischer CA-Eigenschaften in Swift ist ein bisschen knifflig. (Soweit ich weiß, müssen Sie sie mit @NSManaged (!) Annotieren, und Sie müssen needsDisplay(forKey:) überschreiben und true für sie zurückgeben.).