iOS-Entwicklung: Wie kann ich auf dem Gerät Warnungen zu wenig Speicher auslösen?


91

Ich möchte meine App-Funktionen unter Bedingungen mit wenig Speicher gut testen, aber es ist schwierig zu testen. Wie kann ich Warnungen zu wenig Speicher auslösen, die in meinen Ansichten die didReceiveMemoryWarning-Methode auslösen, wenn die App auf dem Gerät und nicht auf dem Simulator ausgeführt wird? Oder wie kann ich meine App unter diesen möglichen Bedingungen testen?

Der Grund, warum ich den Simulator nicht verwenden kann, ist, dass meine App Game Center verwendet und Einladungen nicht auf dem Simulator funktionieren.

Antworten:


8

Fügen Sie zum Testen auf einem Gerät einfach Code hinzu, der regelmäßig große Speicherblöcke zuweist, ohne ihn freizugeben (dh absichtlich zu verlieren). Sie können dies in einem separaten Thread oder als Reaktion auf einen Timer tun oder einen beliebigen Mechanismus verwenden, mit dem Sie das Verhalten Ihrer Anwendung am besten testen und beobachten können.

Sie können auch eine separate App erstellen, die ähnliche Aktionen ausführt und im Hintergrund ausgeführt werden soll, wenn Sie diese problemlos wiederverwenden und / oder mit mehreren Anwendungen testen möchten.


7
nicht sehr praktisch. Die Lösung, eine private
Testmethode aufzurufen,

4
Keine gute Lösung, wenn Sie ein reales Szenario betrachten möchten. Sie lähmen die App aufgrund eines Lecks, das nicht auf Speicherdruck zurückzuführen ist. Das ist schlecht, da Sie testen möchten, wie die App im Zustand mit hohem Speicherdruck reagiert. Auf der anderen Seite ist es schwieriger herauszufinden, was das Problem ist, ein echtes Leck oder das falsche, das Sie eingeführt haben. Die private Methode 1 eignet sich besser zum Testen, wie unten angegeben.
Fzaziz

2
Diese Antwort sollte nicht herabgestuft werden, da der zweite Absatz genau das ist, was Apple vorschreibt, wenn Sie das Verhalten Ihrer App testen möchten, wenn der Speicher wirklich knapp wird.
Matt

1
Die Antwort würde mit einem Codeblock verbessert, um diese Zuordnung durchzuführen!
pkamb

Das Einrichten erfordert zwar mehr Arbeit, ist jedoch realistischer als das Aufrufen der privaten Methode. Wenn Ihre App wirklich unter kritischem Speicherdruck steht, kann Ihre App dann die Aktionen ausführen, die Sie ihr befehlen? Und werden diese Aktionen die Situation entlasten oder verschlimmern und dazu führen, dass iOS sie beendet? Außerdem funktioniert die private Methode nicht zum Testen von DISPATCH_SOURCE_TYPE_MEMORYPRESSURE.
jk7

276

Sie können die private Methode aufrufen :

[[UIApplication sharedApplication] performSelector:@selector(_performMemoryWarning)];

Denken Sie daran, es nur beim Debuggen zu verwenden, da Ihre App sonst abgelehnt wird.


6
Es scheint, dass dieser Code die Speicherwarnung auf dem Gerät genau simuliert. Danke Enzo!
William Denniss

28
Anstatt dies im Code zu verwenden, führen Sie es im Debugger aus. po [[UIApplication sharedApplication]performSelector:@selector(_performMemoryWarning)]
Drücken Sie

17
Anstatt po zu verwenden, verwenden Sie expr, dhexpr (void)[[UIApplication sharedApplication] performSelector:@selector(_performMemoryWarning)];
Andy

11
Im Debugger müssen Sie die expr (void)[[UIApplication sharedApplication] _performMemoryWarning]
Problemumgehung

3
Für alle, die dies mit Swift tun expr UIApplication.sharedApplication().performSelector("_performMemoryWarning")#selector
möchten

27

Mit dem Simulate Memory WarningMenüpunkt des iOS-Simulators können Sie eine Speicherwarnung simulieren.


Die einzige Möglichkeit, dies auf dem Gerät zu überprüfen, besteht darin, es tatsächlich zu erzwingen, dh indem Sie die App für längere Zeiträume oder intensive Bilder verwenden oder was Sie haben, wird von App zu App variieren. Ein Vorschlag könnte sein, ein älteres Gerät (3g vielleicht?) Anstelle eines iPhone 4 zu verwenden, damit Sie schneller zur Warnung gelangen.
Jesse Naugher

Danke, Jesse, ich denke, ich werde meiner App nur einige Hacks hinzufügen, um Einladungen zu simulieren, damit ich sie im Simulator ausführen und auf diese Weise die Speicherwarnungen auslösen kann.
BeachRunnerFred

10
Frage war über die Simulation auf dem Gerät.
KPM

20

Verwenden Sie bei Instrumenten den Menüpunkt: Instrument -> Speicherwarnung simulieren.

Verwenden Sie den Menüpunkt Produkt -> Profil, um Instrumente über Xcode in Ihrer App zu verwenden.


Das ist noch besser.
Zappel

@OrangeDog Was ist los?
ThomasW

2
Naja nichts. Wenn ich Enzos Antwortansichten verwende, müssen sie neu geladen werden, wenn ich zu ihnen zurückkehre, nicht mit dieser Methode.
OrangeDog

12

Ich habe Enzo Trans Antwort in Swift neu geschrieben :

UIControl().sendAction(Selector(("_performMemoryWarning")), to: UIApplication.shared, for: nil)

Vielen Dank! Xcode warnt vor "keine mit Objective-C-Selektor deklarierte Methode", dies funktioniert jedoch trotzdem.
Mann1

10

Wenn jemand aus irgendeinem Grund versucht, dies in Swift 4 zu tun, erfahren Sie hier, wie Sie 1,2 GB RAM zuweisen.

let d = Data.init(repeating: 100, count: 1200000000)
  • Dies ist hilfreich, um in anderen Apps eine Warnmeldung auszulösen

Verschleiert so etwas die tatsächlichen Speicherinformationen, die ich in Instruments anzeigen möchte? Obwohl ich sehe, dass es auf einem physischen Gerät keinen richtigen Weg gibt, dies zu tun, scheint es, als würde dies dazu führen, dass alle Daten verzerrt werden, und ich werde nein habe länger eine relative Antwort. Ich werde immer noch sehen, was mehr aufnimmt , aber nicht die wahren Proportionen.
Jake T.

das stürzt sofort ab
Daniel Springer

8

Es gibt einen Menübefehl, der es aufruft.

Hardware > Simulate Memory Warning vom Simulator.


7
Frage war über die Simulation auf dem Gerät.
KPM

2
In Xcode 10 befindet es sich jetzt unter Debug> Simulation simulieren.
Sebbo

7

@ChikabuZ in Swift 3 konvertiert:

UIControl().sendAction(Selector(("_performMemoryWarning")), to: UIApplication.shared, for: nil)

4

Wenn jemand aus irgendeinem Grund versucht, dies in Swift 3 zu tun, erfahren Sie hier, wie Sie 1,2 GB RAM zuweisen.

   for i in 0...1200 {
      var p: [UnsafeMutableRawPointer] = []
      var allocatedMB = 0
      p.append(malloc(1048576))
      memset(p[allocatedMB], 0, 1048576);
      allocatedMB += 1;
   }

3
let d = Data.init (Wiederholung: 100, Anzahl: 1200000000)
Adobels

2
@ Adobels du solltest das als Antwort posten :)
Koen.

1

Swift 4:

UIApplication.shared.perform (Selector (("_ performMemoryWarning")))

Kann das oben genannte als Antwort auf ein Ereignis / eine Benachrichtigung ausführen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.