2013-11-22 12 views
27

Ich habe festgestellt, dass meine App Speicher verliert, aber wenn ich die MKMapView aus dem Speicher Problem weggeht.Stop iOS 7 MKMapView von undichten Speicher

Um die Theorie zu testen, machte ich ein totes einfaches Projekt, das eine Ansicht hat, die eine Ansicht mit einem MKMapView darin schiebt und knallt und schiebt. Nichts mehr. Kein Code in den View-Controllern, alles über Storyboard.

Wenn ich in der Kartenansicht hin und her gehe, beginnt es etwa 3MB nach dem Drücken und Öffnen der Ansicht mit der Karte darin etwa 15 mal der Speicher ist etwa 230MB.

Sonst jemand anderes gesehen? Scheint wie ein ziemlich großer Käfer. Gibt es einen anderen Weg, MKMapView zu verwenden, der verhindert, dass es so viel ausleckt?

enter image description here

+2

Ich sehe dieses Verhalten auch in meiner App und für mich ist die Frage klar: Was passiert hier? Ist das ein echtes Speicherleck (es scheint so) und hat jemand herausgefunden, was schief läuft und wie man es beheben kann. –

+0

Versuchen Sie, die MKMapView in der Methode viewDidDisappear zu entfernen, Beispiel: [self.outMapView removeFromSuperview]; self.outMapView = null; –

+0

sollte wahrscheinlich ein Radarticket protokollieren. – johndpope

Antwort

12

hatte ich das gleiche Problem konfrontiert und (dank Stackoverflow) fixiert es durch MKMapType in viewWillDisappear und Aufheben der Zuordnung zu ändern/Einstellung seiner Delegierten nil.As sendet er noch Nachricht an die Delegierten. Dies ist in MKMapViewDelegate-Protokoll-Referenz dokumentiert:

ein MKMapView Objekt vor der Freigabe für die Sie einen Delegierten festgelegt haben, daran erinnern, dass Objekt des Delegierten-Eigenschaft auf Null zu setzen. Ein Ort, den Sie dies tun können, ist in dem dealloc Verfahren, in dem Sie von entsorgen die Kartenansicht

.

-(void)viewWillDisappear:(BOOL)animated{ 
    [super viewWillDisappear:animated]; 
    [self applyMapViewMemoryFix]; 

} 

- (void)applyMapViewMemoryFix{ 

switch (self.mkMapView.mapType) { 
    case MKMapTypeHybrid: 
    { 
     self.mkMapView.mapType = MKMapTypeStandard; 
    } 

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

     break; 
    default: 
     break; 
} 
self.mkMapView.showsUserLocation = NO; 
self.mkMapView.delegate = nil; 
[self.mkMapView removeFromSuperview]; 
self.mkMapView = nil; 
} 

hoffe, das hilft

+5

Hilft nicht. Immer noch undicht. – durazno

+0

Ja, es ist auch immer noch für mich undicht. Ich habe die Kartenansicht in einer 'UICollcetionViewCell', so dass ich diesen Code nicht von' viewWillDisappear' aufrufen kann. Es in der Zelle "deinit" aufzurufen, funktioniert nicht. – fruitcoder

+1

Haben wir ein Update? es ist 2018 und immer noch [email protected] – dreamBegin

3

Swift Version:

override func viewWillDisappear(animated:Bool){ 
    super.viewWillDisappear(animated) 
    self.applyMapViewMemoryFix() 
} 

func applyMapViewMemoryFix(){ 
    switch (self.mapView.mapType) { 
     case MKMapType.Hybrid: 
      self.mapView.mapType = MKMapType.Standard 
      break; 
     case MKMapType.Standard: 
      self.mapView.mapType = MKMapType.Hybrid 
      break; 
     default: 
      break; 
    } 
    self.mapView.showsUserLocation = false 
    self.mapView.delegate = nil 
    self.mapView.removeFromSuperview() 
    self.mapView = nil 
} 
+2

Ich habe immer noch Speicherproblem in iOS 8.3/8.4, obwohl ich Ihre Lösung implementiert – user2722667

3

Die beste Lösung, die ich gefunden habe, ist eine Instanz von MKMapView in Ihrem Delegierten haben, können Sie es nur einmal vergeben wird.

Dann immer wenn Sie eine MapView benötigen, verwenden Sie nur die eine von der Stellvertretung.

In meinem Fall musste ich die Anmerkungen löschen, sobald die Ansicht verschwindet (um keine älteren Anmerkungen auf der Karte zu haben).

- (void)viewDidLoad { 
     AppDelegate *delegate = [UIApplication sharedApplication].delegate; 
      if (!delegate.appModel.mapView) 
      delegate.appModel.mapView = [[MKMapView alloc] initWithFrame:self.view.frame]; 
     self.mapView = delegate.appModel.mapView; 
     [self.mapView setFrame:self.view.frame]; 
     [self.mapView setDelegate:self]; 
     [self.view addSubview:self.mapView]; 
    } 

- (void)viewWillDisappear:(BOOL)animated { 
    [super viewWillDisappear:animated]; 
    [self.mapView removeAnnotations:self.mapView.annotations]; 
    for (id<MKOverlay> overlay in self.mapView.overlays) { 
     [self.mapView removeOverlay:overlay]; 
    } 
} 
+0

Eine statische Variable wird tun (anstatt es in einer Anwendung Delegate Variable zu speichern) –