Подтвердить что ты не робот

Остановить iOS 7 MKMapView от утечки памяти

Я заметил, что мое приложение утечки памяти, но если я возьму MKMapView, проблема с памятью исчезнет.

Чтобы проверить теорию, я сделал простой проект, который имеет представление, которое подталкивает в него представление MKMapView, и выталкивает и толкает. Больше ничего. Никакого кода в контроллерах просмотра, все, что сделано через раскадровку.

Если я перехожу назад и вперед к виду карты, он начинается примерно с 3 МБ после того, как вы нажимаете и выталкиваете представление с картой в нем, примерно в 15 раз больше, чем около 230 МБ.

Кто-нибудь еще видел это? Кажется, это довольно большая ошибка. Есть ли другой способ использования MKMapView, который предотвратит его утечку?

enter image description here

4b9b3361

Ответ 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
}