5

Ich möchte etwas über Speicherverwaltung in Objective-C lernen, was ich nicht so einfach finde, weil ich ziemlich neu in Objective-C und ARC bin und meistens Skriptsprachen benutze, für die ich nicht muss so viel (oder gar nicht) mit der Speicherverwaltung zu tun haben.Wenn ein View-Controller geschlossen wird, sollte er den Speicher leeren?

Die App, an der ich arbeite, präsentiert einen ViewController (mit XIB-Datei angehängt) aus Code nach dem Drücken einer Taste. In diesem View-Controller habe ich mehrere Ansichten instanziiert; Ich nehme eine Sequenz von Bildern auf (Fotos von der Kamera, gespeichert auf der Festplatte), die ich in einen Film umwandele, und ich habe einen GPS-Tracker (mapKit), der eine kleine Karte auf dem Bildschirm anzeigt. Nachdem alles getan wird, kann ich ein ‚done‘ Knopf drücken, die [self dismissViewControllerAnimated:YES completion:nil];

ruft die Viewcontroller zurück zu meinem RootViewController animiert sind und weil ich legte eine NSLog Mitteilung innerhalb der dealloc Methode in dem Viewcontroller, dass ich diese Viewcontroller bestätigen kann entlassen werden wird freigegeben.

Das Problem ist, dass ich den Speicher steigen sehen nach der Verwendung der App (Nutzung besteht aus Aufnahmen und Aufnahme GPS-Positionen auf einer MapKit-Karte sowie das Erstellen einer Filmdatei) auf etwa 80 MB und das auf etwa sinkt 70MB, wenn ich "fertig" drücke, so dass der viewController die App beendet und die App zu meinem rootViewController zurückkehrt. Ich kann den gleichen viewController wieder präsentieren, benutze es und verlasse es, und die App wird immer noch rund 70MB Speicher belegen, der nicht abfällt. Das sieht für mich nicht wirklich wie ein Speicherleck aus, denn in diesem Fall würde ich mit jeder Instanziierung und Entlassung des viewControllers einen stetigen Speicheranstieg erwarten. Dies ist selbst dann nicht der Fall, wenn ich in meinem rootViewController verschiedene Schaltflächen habe, die alle eine neue und eindeutige Instanz meiner viewController-Klasse instanziieren.

Ich frage mich: Gibt es etwas, nach dem ich suchen sollte oder ist das erwartete Verhalten? Vielleicht speichert die App Klassen für die zukünftige Verwendung? Wenn die Speicherverwaltung richtig ausgeführt wird, sollte ich erwarten, dass eine App in den Zustand "jungfräulich" zurückkehrt (in diesem Fall wären es etwa 4 MB), nachdem der einzige dargebotene viewController abgelehnt wurde?

+1

Profilieren Sie die App mit * Leaks * unter 'Instruments'. – trojanfoe

+0

Fertig, keine Lecks erkannt. – Hype1

+0

Vielleicht möchten Sie [diese Q & A] lesen (http://stackoverflow.com/q/12641658/335858), es spricht über MapKit Speicherproblem. Die Q & A ist jedoch alt, also könnte es angesprochen worden sein. – dasblinkenlight

Antwort

6

Wenn Sie diesen Speicher Anstieg in Xcode sehen und nicht als Instrumente dann the answer I have come up with is in this answer.

Sie, dass die ganze Antwort lesen kann, es ist ziemlich in der Tiefe.Aber kurz gesagt, in Xcode sehen Sie die Menge an Speicher, die das Betriebssystem Ihrer App gegeben hat. Dies wird sich jedes Mal erhöhen, wenn Ihre App versucht, etwas zuzuweisen. Es verringert sich nicht so schnell, da das Betriebssystem Leistung vermutet, wenn Sie davon ausgehen, dass Ihre App in Zukunft möglicherweise mehr Speicher benötigt. Es ist schneller für das Betriebssystem, den Speicher, der Ihrer App "gegeben" wurde, zu verlassen, als ihn zu entfernen und später zurückzugeben.

+1

Wow, vielen Dank! Ich habe den ganzen Tag nach Fehlern in meinem App-Code gesucht und ARC- und Speicherverwaltung gelesen und es ist mir nie in den Sinn gekommen, dass der Speicherwert etwas mit Speicher zu tun haben würde, der vom Betriebssystem zugewiesen wird, anstatt in diesem Moment tatsächlich benötigt zu werden. Ich hatte nur diese App aktiv und für den Test habe ich auch ein paar 3D-Spiele aktiviert und dann bemerkte ich, dass die Speichernutzung meiner App sofort abbrach. Ich habe einen Arbeitstag verloren, aber ich habe viel gelernt. :) – Hype1

2

Der View-Controller sollte aus dem Speicher gelöscht werden, wenn er nicht von anderen Objekten verwendet wird (oder keine starken Verbindungen zu anderen Objekten hat, die noch nicht aus dem Speicher entfernt wurden).

Ex.

class ViewController: UIViewController { 
    var secondViewController: SecondViewController? 
    override func viewDidLoad() { 
     super.viewDidLoad() 
    } 
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
     if let identifier = segue.identifier { 
      if identifier == "second" { 
       if secondViewController == nil { 
        secondViewController = segue.destinationViewController as? SecondViewController 
       } else { 
        println("There's still an instance of second view controller") 
       } 
      } 
     } 
    } 
} 

Angenommen, Sie die secondViewController das erste Mal präsentiert das Storyboard segue verwenden, und speichern Sie es in Ihrem Fall eines Viewcontroller als Eigenschaft. Wenn Sie dann den secondViewController schließen und den zweiten ViewController erneut von ViewController präsentieren, wird "Es gibt immer noch eine Instanz des zweiten View-Controllers" angezeigt, da der von Ihnen zuvor dargestellte ViewController noch immer von ViewController verwendet wird.

Wenn der secondViewController jedoch eine schwache Verbindung hat (weak var secondViewController: SecondViewController), wird er niemals gedruckt, da ab dem Zeitpunkt, an dem der secondViewController beendet wurde, er aus dem Speicher entfernt wird und secondViewController gleich null ist.

EDIT:

Hinweis: Ergebnis sollte gleich sein, wenn Objective-C verwenden.

+0

Danke für deine Zeit und Mühe, aber @ Putz1103 hat mir einfach die Antwort gegeben, die ich brauchte. – Hype1