2013-03-15 28 views
6

Stworzyłem prosty UIViewController, który tworzy i niszczy GMSMapView.wyciek pamięci w GMSMapView

- (void)viewDidAppear:(BOOL)animated 
{ 
    if (!m_disappearing_bc_segue) 
    { 
     [super viewDidAppear:animated] ; 

     GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude: self.location.latitude 
                  longitude: self.location.longitude 
                   zoom:9 ] ; 

     m_mapView = [GMSMapView mapWithFrame:CGRectMake(0, 0, 320, 420) camera:camera]; 

     m_mapView.myLocationEnabled = NO ; 

     [m_mapView setMapType: kGMSTypeTerrain] ; 

     m_mapView.delegate = self ; 

     [self.view addSubview:m_mapView] ; 
     [self.view sendSubviewToBack:m_mapView] ; 
} 



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

    [m_mapView clear] ; 
    [m_mapView stopRendering] ; 
    [m_mapView removeFromSuperview] ; 
    m_mapView = nil ; 
} 

Użyłem instrumentów z instrumentem alokacji. Test jest łatwy. W UINavigation ViewController naciśnij widok, naciśnij i powtórz. Występuje około 40kb przecieku za każdym razem, gdy naciskasz i otwierasz widok zawierający opisany wyżej GMSMapView. Mam zrzut ekranu z Instrumentów, aby to zilustrować, ale stackoverflow nie pozwala mi go opublikować. Mogę wysłać do kogoś przez e-mail, jeśli jest zainteresowany.

Czy robię coś złego lub czegoś brakuje?

+0

Dlaczego za każdym razem potrzebujesz odtwarzać 'GMSMapView'? –

+0

Dowolna szansa dodania m_mapView.delegate = nil; przed powiedzeniem m_mapView = nil go rozwiąże? Może ... –

+0

@SergeyKuryanov Zasadniczo, aby zwolnić pamięć. Każdy GMSMapView zużywa poważną pamięć. Mam mini-widok (połowę ekranu), a przycisk wyświetla widok zmaksymalizowanej wersji. Kiedy wracam z wersji zmaksymalizowanej, chcę ją wyrzucić. – user2101384

Odpowiedz

2

Co pracował dla mnie było usunięcie @try klauzuli miałem w dealloc:

@try { 
    [self.mapView removeObserver:self forKeyPath:@"myLocation"]; 
} 
@catch (NSException *exception) { 
} 

Moim zamiarem było usunięcie self jako obserwator gdy ViewController jest dealloc'd (ironicznie, aby uniknąć problemu z pamięci), a zignoruj ​​wyjątek, jeśli nie jest obserwatorem.

Najwyraźniej @try w jakiś sposób zatrzymuje mapView, co sprawia, że ​​pozostaje w pamięci (przez ARC). Zobacz, dlaczego tutaj: Why does "try catch" in Objective-C cause memory leak?.

Po usunięciu klauzuli @try (i kondycjonowaniu removeObserver z pewną flagą, aby uniknąć wyjątku), pamięć wróciła do normalnego działania!