2009-05-28 10 views
3

Ok ......iPhone Memory Management didReceiveMemoryWarning

Ich bin auf dem iPhone eine einfache OpenGL ES Anwendung Implementierung und ich vor kurzem in Pinch Media Analytics hinzugefügt. Dadurch konnte ein Speicherverwaltungsproblem aufgedeckt werden, und ich bin mir nicht ganz sicher, wie ich damit umgehen soll.

In einer perfekten Welt, meine Anwendung - die gerade fein PNGs und .CAF Dateien in didFinishLoading startet, lädt all seine Ressourcen und führen lädt.

ABER, wenn mein Programm einen Absturz bekommt (was passierte, als ich die Pinch Media Bibliotheken integrierte) oder wenn ich Safari starte und eine Reihe von Seiten öffne und dann mein Spiel starte, stürzt das Spiel wieder auf das Menü ab es ist nicht genug Speicher.

Dieses Problem bleibt bestehen, bis ich einen Hard Reset des Systems mache.

Die Standardantwort, die Sie sortieren Online von bekommen ist die didReceiveMemoryWarning Methode zu implementieren, wie unten aufgeführt ....

- (void)didReceiveMemoryWarning 
{ 
    // default behavior is to release the view if it doesn't have a superview. 

    // remember to clean up anything outside of this view's scope, such as 
    // data cached in the class instance and other global data. 
    [super didReceiveMemoryWarning]; 
} 

Aber das hilft nicht wirklich, wie es die anderen Programme ist, die auf Speicher halten sind nicht mein. Ich möchte meine eigene Sichtweise nicht freigeben, oder? Gibt es eine gute Beschreibung, wie mit dieser Situation umzugehen ist und was im didReceiveMemoryWarning-Ereignis passiert?

Antwort

2

Wenn Sie nur einen einzigen Blick haben, dann ist das einzige, was Sie wirklich tun können, ist jede Daten freizugeben, die Sie nicht verwenden, und faul Last sie später.

Wenn Sie mehr als ein einziger Blick haben, dann könnten sie freigegeben werden, wenn sie nicht sichtbar sind. Wenn dies geschieht, wird der entsprechende Controller mit setView: mit nil gesendet. Ich handle damit, indem ich sofort alle IBOutlet Variablen loslasse, so dass sie richtig eingestellt sind, wenn die Ansicht wieder von ihrem xib geladen wird.

Dies ist der Ansatz, den ich in einer normalen, OpenGL-freien ES-Anwendung mit> 6 Ansichten anwende und auch dann konsistent funktioniert, wenn ich 4 Ebenen tief in einer Navigationsansicht bin und alle früheren Controller auf nil eingestellt sind. Es gibt keinen Absturz, wenn ich rückwärts navigiere, obwohl es eine Verzögerung gibt, wenn die Ansichten neu geladen werden.

Wenn Sie es nicht bereits gefunden haben, im Simulator gibt es einen Menüpunkt eine Speicher Warnung zu simulieren, die als einfacher ist, den Zustand zwingt in einem realen Gerät auftreten. Das heißt, es ersetzt nicht das Testen des gleichen Szenarios in einem echten Gerät - macht nur das Testen einfacher.

+0

Danke. Ich werde versuchen, die Lazy-Load-Methode, da dies nur eine Ansicht hat. – K2Digital

5

Willkommen im Shared-Memory-Pool ohne VM .... Es gibt nicht viel, was Sie hier tun können, aber es gibt ein paar Dinge (und es ist möglich, es ist Ihre Schuld und Sie können es vollständig beheben). Spieleentwickler empfehlen ihren Kunden oft einen Neustart, bevor sie sie aus diesem Grund ausführen. Daher müssen Sie möglicherweise im gleichen Boot sitzen, wenn Sie wirklich viel Speicher benötigen, um effektiv zu sein.

Natürlich sollten Sie versuchen, Ihren eigenen Speicherbedarf zu minimieren. Sie sollten jedoch auch versuchen, eine übermäßige Speicherfragmentierung zu vermeiden. Manchmal besteht das Problem nicht darin, dass es keine Erinnerung gibt; Es gibt einfach keine Blöcke, die groß genug sind. Manchmal ist es besser, ein Mutable zu verwenden und es weiter zu ändern, anstatt ein neues unveränderliches Objekt zu generieren. Dies gilt insbesondere für große NSStrings, die Speicher wirklich zerstören können.

Denken Sie daran, dass UIImage +imageNamed: das Bild nach der Veröffentlichung erhalten bleibt, wenn Sie sie also nicht mehr benötigen, müssen Sie diese löschen. Setzen Sie den Namen auf nil, bevor Sie ihn freigeben, um das Caching zu stoppen.

Stellen Sie sicher, dass Sie Ihre App unter Instrumente ausführen. Vielleicht isst du mehr Gedächtnis, als du denkst.

Vergessen Sie nicht den Autorelease-Pool. Wenn Sie in einer einzelnen Ereignisschleife viele automatisch wiederhergestellte Objekte generieren, müssen Sie Ihren Pool möglicherweise regelmäßig leeren, damit Ihr Speicher nicht ausgelastet wird. Speicherspitzen können dazu führen, dass ein Programm mit geringen Speicheranforderungen plötzlich beendet wird.

+0

Danke Rob. Ich gebe das eine Chance. – K2Digital

+0

Wenn Sie sagen "Führen Sie Ihre App unter Instrumenten", ist die interessanteste Maßnahme "Live Bytes?" –

+0

In der Regel verwende ich das Allocations-Instrument mit "Created & Still Living" als Lebensdauer (das ist die Standardeinstellung). Ich mag es auch besonders, die Track-Anzeige (klicke den "i") Style auf "Allocation Density" zu setzen. Dies gibt Ihnen die erste Ableitung der Anzahl der verwendeten Bytes, die es einfach macht, Orte zu finden, denen Sie plötzlich viel Speicher zuweisen. –

0

Sie könnten versuchen, komprimiertes PVRTC anstelle von PNG zu verwenden, um etwas Platz zu sparen (bei möglichen Leistungskosten).

Es gibt ein schönes kleines Tutorial hier:

http://iphonedevelopment.blogspot.com/2008/12/preparations-for-porting-nehe-lesson-06.html

Und denken Sie daran, ruft Sie ein paar Ihrer OpenGL neu zu schreiben, haben diese verschiedenen komprimierten Textur zu handhaben.

[Haftungsausschluss: Ich bin kein OpenGL ES Optimierung Guru. Nicht durch einen laaaaaangen Schuss.]

Verwandte Themen