2013-03-15 6 views
6

Ho creato un semplice UIViewController che crea e distrugge un GMSMapView.perdita di memoria in 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 ; 
} 

Ho usato gli strumenti con lo strumento Allocations. Il test è facile. In un ViewController di UINavigation, premi la vista, premi indietro e ripeti. C'è una perdita di circa 40kb ogni volta che si spinge e si apre la vista contenente il GMSMapView descritto sopra. Ho uno screenshot degli strumenti per illustrare questo, ma StackOverflow non mi permette di pubblicarlo. Posso inviare a qualcuno per email se interessato.

Sto facendo qualcosa di sbagliato o mi manca qualcosa?

+0

Perché è necessario ogni volta per ricreare 'GMSMapView'? –

+0

Ogni possibilità di aggiungere m_mapView.delegate = nil; prima di dire m_mapView = nil lo risolverà? Potrebbe ... –

+0

@SergeyKuryanov Fondamentalmente per liberare memoria. Ogni GMSMapView consuma memoria seria. Ho una mini-view (metà dello schermo) e un pulsante ti spinge a vedere una versione ingrandita. Quando torno dalla versione ingrandita, voglio buttarlo via. – user2101384

risposta

2

Quello che ha funzionato per me è stata la rimozione della clausola di @try che avevo in dealloc:

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

La mia intenzione era quella di rimuovere self in qualità di osservatore quando l'ViewController è dealloc'd (ironicamente per evitare un problema di memoria), e ignorare l'eccezione se non è un osservatore.

Apparentemente @try mantiene in qualche modo il mapView, che lo fa rimanere in memoria (via ARC). Vedi perché qui: Why does "try catch" in Objective-C cause memory leak?.

Dopo aver rimosso la clausola @try (e condizionando lo removeObserver con qualche contrassegno per evitare l'eccezione), la memoria tornava a comportarsi normalmente!