Остановить iOS 7 MKMapView от утечки памяти
Я заметил, что мое приложение утечки памяти, но если я возьму MKMapView
, проблема с памятью исчезнет.
Чтобы проверить теорию, я сделал простой проект, который имеет представление, которое подталкивает в него представление MKMapView
, и выталкивает и толкает. Больше ничего. Никакого кода в контроллерах просмотра, все, что сделано через раскадровку.
Если я перехожу назад и вперед к виду карты, он начинается примерно с 3 МБ после того, как вы нажимаете и выталкиваете представление с картой в нем, примерно в 15 раз больше, чем около 230 МБ.
Кто-нибудь еще видел это? Кажется, это довольно большая ошибка. Есть ли другой способ использования MKMapView
, который предотвратит его утечку?
![enter image description here]()
Ответы
Ответ 1
Я столкнулся с той же проблемой и (благодаря Stackoverflow) исправил ее, изменив MKMapType
в viewWillDisappear
и освободив/установив ее делегат в nil.As он по-прежнему отправляет сообщение делегатам.
Это описано в MKMapViewDelegate Protocol Reference:
Перед выпуском объекта MKMapView, для которого вы установили делегат, не забудьте установить для свойства делегирования объектов значение nil. Один место, которое вы можете сделать, это метод dealloc, в котором вы распоряжаетесь вид карты
.
-(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;
}
надеюсь, что это поможет
Ответ 2
Лучшим решением, которое я нашел, является наличие экземпляра MKMapView в вашем делетете, вы будете выделять его только один раз.
Затем в любое время, когда вам нужен MapView, вы просто используете его из делегата.
В моем случае мне нужно было очистить аннотации от него, как только откроется представление (не иметь более старых аннотаций на карте).
- (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];
}
}
Ответ 3
Быстрая версия:
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
}