2014-10-20 24 views
5

Przeczytałem inne pytania i odpowiedzi związane z StackOverflow i rozumiem, że jest to błąd, ponieważ iOS6 (lub przez projekt, musiał zwolnić delegata, a następnie wyświetlić, kto wie). Nie wiem, dlaczego i jak nie zostało to naprawione.Wyciek pamięci w MapKit iOS8

Anywho, dodałem poprawek od innych odpowiedzi (poniżej, dla przyszłych czytelników):

- (void) viewDidDisappear:(BOOL)animated 
{ 
    [super viewDidDisappear:animated]; 
    [self applyMapViewMemoryHotFixOnDisappear]; 
} 

- (void)applyMapViewMemoryHotFixOnDisappear{ 
    [self applyMapViewMemoryHotFix]; 
    self.mapView.showsUserLocation = NO; 
    self.mapView.delegate = nil; 
    self.locationManager.delegate = nil; 
    [self.mapView removeFromSuperview]; 
    self.mapView = nil; 
} 

- (void)applyMapViewMemoryHotFix{ 
    switch (self.mapView.mapType) { 
     case MKMapTypeHybrid: 
     { 
      self.mapView.mapType = MKMapTypeStandard; 
     } 

      break; 
     case MKMapTypeStandard: 
     { 
      self.mapView.mapType = MKMapTypeHybrid; 
     } 

      break; 
     default: 
      break; 
    } 
    self.mapView.mapType = MKMapTypeStandard; 
} 

-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated 
{ 
    [self applyMapViewMemoryHotFix]; 
} 

Jednak mam pytanie jest, dlaczego pamięć nie spadnie do poziomu przed MapKit ?

Memory Usage Before/After MapKit

Czy jest coś jeszcze mi brakuje? Czy to oczekiwane zachowanie? Nie ma wycieków pamięci ocenianych przez profilera, ale oczywiście coś jest nie w porządku ...

+0

widzę to samo. Znalazłeś jakieś rozwiązanie? – thejaz

+1

Nie!Szczerze mówiąc, nie stosuj nawet "poprawki" w zmienionym regionie. "Wyciek pamięci" (jeśli nawet taki jest) jest w porządku i nie jest zauważalny na prawdziwym urządzeniu, a nie rośnie, co jest miłe. – SparkyRobinson

+1

Zgadzam się, zauważyłem, że było znacznie lepiej na urządzeniu niż na symulatorze. – thejaz

Odpowiedz

1

Pomimo użycia tak ukochanego MemoryHotFix przez społeczność SO w odniesieniu do tego problemu, powinieneś być pewien, że nie trzymasz żadnych silne referencje. Jak powiedzieli inni, jeśli używasz widoków (odczytujących instancję), które zawierają odniesienie do kontrolera widoku, w którym się znajdują i tego samego kontrolera widoku, jako odniesienia do tego widoku, możesz przejść do Silnego cyklu odniesienia.

Sytuacja taka może zablokować metody deinit/dealloc, co spowoduje, że Twoje porządki będą niepotrzebne i bezużyteczne.

Jak stwierdzono w documentation:

można rozwiązać silnych cykli odniesienia definiując niektóre relacje między klasami za słabych lub bezpańskich referencje zamiast jak silnymi odniesieniami.

Więc należy:

  1. sprawdzić, czy deinit (Swift)/dealloc jest faktycznie nazywa (jeśli nie, może to oznaczać Mocne cyklu odniesienia).
  2. Właściwie zeruj delegatów menedżerów MKMapView i LocalitionManager oraz samych siebie.

Jak to:

self.mapView.delegate = nil 
self.mapView = nil 
self.locationManager?.delegate = nil 
self.locationManager = nil 

Dowód

Mając to na uwadze, tutaj jest przykładem, gdzie znajduje się jedna VC pchania innego VC z MKMapView, każda pionowa czerwona linia oznacza " pchanie nowego VC "i każda zielona linia oznacza" popping it ":

enter image description here

Istnieje początkowa konfiguracja (od 50 Mb +/-), ale przyszłe wypychania nie powodują wycieku pamięci, jak pokazano. Warto wspomnieć, że został on przechwycony przy użyciu prawdziwego urządzenia. Przetestowałem to również za pomocą symulatora, a wyniki są koherentne, mimo że początkowa konfiguracja była znacznie wyższa (zaczynając od 100 Mb).

nadzieję, że chłopaki mogą go naprawić i to polubisz, a także sprawdzić swój projekt dla silnych cykli odniesienia, które mogłyby naruszyć swój produkt w przyszłości;)