ios objective-c memory-management memory-leaks mkmapview

Evite que iOS 7 MKMapView tenga pérdidas de memoria



objective-c memory-management (3)

La mejor solución que he encontrado es tener una instancia de MKMapView en tu delegado, la asignarás solo una vez.

Luego, cada vez que necesite un MapView, simplemente use el del delegado.

En mi caso, tuve que limpiar las anotaciones tan pronto como la vista desaparecerá (para no tener anotaciones antiguas en el mapa).

- (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]; } }

Me di cuenta de que mi aplicación pierde memoria, pero si saco el MKMapView , el problema de memoria desaparece.

Para probar la teoría, hice un proyecto muerto simple que tiene una vista que empuja una vista con un MKMapView y aparece y empuja. Nada mas. No hay código en los controladores de vista, todo se hace a través del guión gráfico.

Si voy de ida y vuelta a la vista del mapa, comienza aproximadamente 3 MB después de empujar y hacer estallar la vista con el mapa en ella, esto unas 15 veces la memoria es de alrededor de 230 MB.

¿Alguien más ha visto esto? Parece un error bastante grande. ¿Hay alguna manera diferente de usar MKMapView que MKMapView que MKMapView tanto?


Me enfrenté al mismo problema y (gracias a ) lo solucioné cambiando MKMapType en viewWillDisappear y desasignando / estableciendo su delegate en nil. Como todavía envía un mensaje a los delegados. Esto está documentado en MKMapViewDelegate Protocol Reference:

Antes de liberar un objeto MKMapView para el que haya establecido un delegado, recuerde establecer la propiedad de delegado de ese objeto en cero. Un lugar donde puedes hacer esto es en el método dealloc donde desechas la vista del mapa

.

-(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; }

espero que esto ayude


Versión Swift:

override func viewWillDisappear(_ animated:Bool) { super.viewWillDisappear(animated) self.applyMapViewMemoryFix() } func applyMapViewMemoryFix() { switch (self.mapView.mapType) { case MKMapType.hybrid: self.mapView.mapType = MKMapType.standard case MKMapType.standard: self.mapView.mapType = MKMapType.hybrid default: break } self.mapView.showsUserLocation = false self.mapView.delegate = nil self.mapView.removeFromSuperview() self.mapView = nil }