Rozwój iOS: Jak wywołać ostrzeżenia o małej ilości pamięci na urządzeniu?


93

Chciałbym sprawdzić, czy moja aplikacja działa dobrze w warunkach małej ilości pamięci, ale jest to trudne do przetestowania. Jak mogę wywołać ostrzeżenia o małej ilości pamięci, które wyzwalają metodę didReceiveMemoryWarning w moich widokach, gdy aplikacja jest uruchomiona na urządzeniu, a nie na symulatorze? Albo jakie są sposoby na przetestowanie aplikacji w tych możliwych warunkach?

Nie mogę używać symulatora, ponieważ moja aplikacja korzysta z Game Center, a zaproszenia nie działają na symulatorze.

Odpowiedzi:


9

Aby przetestować na urządzeniu, po prostu dodaj kod, który okresowo przydziela duże fragmenty pamięci bez jej zwalniania (tj. Celowo wycieka). Możesz to zrobić w osobnym wątku, w odpowiedzi na licznik czasu lub przy użyciu dowolnego mechanizmu, który najlepiej pozwala na testowanie i obserwowanie zachowania aplikacji.

Możesz także utworzyć oddzielną aplikację, która robi coś podobnego i jest zaprojektowana do działania w tle, jeśli chcesz łatwo ponownie użyć tej aplikacji i / lub przetestować ją z wieloma aplikacjami.


7
niezbyt praktyczne. lepszym rozwiązaniem jest wywołanie prywatnej metody testowania
Daij-Djan

5
Nie jest to dobre rozwiązanie, jeśli chcesz spojrzeć na scenariusz z prawdziwego świata. Uszkadzasz aplikację z powodu wycieku, a nie z powodu presji pamięci. To źle, ponieważ to, co chcesz zrobić, to przetestować, jak aplikacja reaguje w stanie wysokiego obciążenia pamięci. Z drugiej strony trudniej jest ustalić, na czym polega prawdziwy wyciek lub fałszywy, który wprowadziłeś. Metoda prywatna jest lepsza do testowania, jak podano poniżej.
fzaziz

2
Nie należy lekceważyć tej odpowiedzi, ponieważ drugi akapit jest właściwie tym, co Apple mówi, aby zrobić, jeśli chcesz przetestować zachowanie aplikacji, gdy pamięć jest naprawdę niska.
mat.

1
Odpowiedź byłaby ulepszona za pomocą bloku kodu do wykonania tej alokacji!
pkamb

Chociaż konfiguracja wymaga więcej pracy, jest to bardziej realistyczny test niż wywołanie metody prywatnej. Kiedy naprawdę występuje krytyczne obciążenie pamięci, czy Twoja aplikacja będzie w stanie wykonać polecenia, które jej nakazujesz? Czy te działania złagodzą sytuację, czy ją pogorszą i spowodują, że iOS ją zakończy? Poza tym metoda prywatna nie działa do testowania DISPATCH_SOURCE_TYPE_MEMORYPRESSURE.
jk7

278

Możesz wywołać metodę prywatną :

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

Pamiętaj tylko, aby używać go tylko do debugowania, w przeciwnym razie Twoja aplikacja zostanie odrzucona.


6
Wygląda na to, że ten kod dokładnie symuluje ostrzeżenie dotyczące pamięci na urządzeniu. Dzięki Enzo!
William Denniss

28
Zamiast używać tego w kodzie, wykonaj go w debugerze. Po prostu naciśnij pauzę i wejdźpo [[UIApplication sharedApplication]performSelector:@selector(_performMemoryWarning)]
orkoden

17
Zamiast używać po, użyj wyrażenia, np.expr (void)[[UIApplication sharedApplication] performSelector:@selector(_performMemoryWarning)];
Andy

11
W debugerze nie musisz stosować obejścia, aby nie mieć nagłówka:expr (void)[[UIApplication sharedApplication] _performMemoryWarning]
OrangeDog

3
Dla każdego, kto chce to zrobić za pomocą Swift: wpisz expr UIApplication.sharedApplication().performSelector("_performMemoryWarning")zamiast zwykłego#selector
funct7

29

Simulate Memory WarningPozycja menu symulatora iOS umożliwia symulację ostrzeżenia dotyczącego pamięci.


Jedynym sposobem sprawdzenia tego na urządzeniu jest faktyczne wymuszenie tego, tj. Używanie aplikacji przez długi czas lub intensywne obrazy lub to, co masz, będzie się różnić w zależności od aplikacji. Sugestią może być użycie starszego urządzenia (może 3g?) Zamiast iPhone'a 4, aby szybciej uzyskać ostrzeżenie.
Jesse Naugher

Dzięki, Jesse, myślę, że po prostu dodam kilka hacków do mojej aplikacji, aby zasymulować zaproszenia, aby móc uruchomić ją w symulatorze i w ten sposób wywołać ostrzeżenia dotyczące pamięci.
BeachRunnerFred

10
Pytanie dotyczyło symulacji na urządzeniu.
KPM

20

Używając Instrumentów, użyj pozycji menu: Instrument -> Symulacja ostrzeżenia pamięci.

Aby używać instrumentów w swojej aplikacji z Xcode, użyj pozycji menu Produkt -> Profil.


To jest jeszcze lepsze.
Zappel

@OrangeDog Co się dzieje?
Thomas W

2
Jak nic. Kiedy używam odpowiedzi Enzo, widoki muszą się ponownie ładować, kiedy do nich wracam, a nie przy użyciu tej metody.
OrangeDog

12

Mam ponownie napisany odpowiedź Enzo Tran w Swift:

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

Dzięki! Xcode ostrzega przed „brakiem metody zadeklarowanej za pomocą selektora Objective-C”, ale to działa.
man1

10

Jeśli ktoś z jakiegoś powodu spróbuje to zrobić w Swift 4 - oto jak przeznaczyć 1,2 GB pamięci RAM.

let d = Data.init(repeating: 100, count: 1200000000)
  • Jest to pomocne przy uruchamianiu ostrzeżenia w innych aplikacjach

Czy zrobienie czegoś takiego zaciemni rzeczywiste informacje w pamięci, które próbuję wyświetlić w Instruments? Chociaż widzę, że nie ma właściwego sposobu, aby to zrobić na urządzeniu fizycznym, jeśli chodzi mi o sprawdzenie, co zajmuje moją pamięć w mojej aplikacji, wydaje się, że spowoduje to wypaczenie wszystkich danych, a ja nie mają już względną odpowiedź. Nadal zobaczę, co zajmuje więcej , ale nie prawdziwe proporcje.
Jake T.

to się zawiesza natychmiast
Daniel Springer

8

Przekonwertowano @ChikabuZ na swift 3:

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

7

Istnieje polecenie menu, które go wywoła.

Hardware > Simulate Memory Warning z symulatora.


8
Pytanie dotyczyło symulacji na urządzeniu.
KPM

2
W Xcode 10 jest teraz pod ostrzeżeniem Debug> Simulate Memory.
Sebbo

4

Jeśli ktoś z jakiegoś powodu spróbuje to zrobić w Swift 3 - oto jak przeznaczyć 1,2 GB pamięci RAM.

   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 (powtarzanie: 100, liczba: 1200000000)
Blazej SLEBODA

2
@Adobels powinieneś to zamieścić jako odpowiedź :)
Koen.

1

Swift 4:

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

Może wykonać powyższe w odpowiedzi na zdarzenie / powiadomienie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.