Reputation: 2906
Getting leaks in profiler when google map loads. I have created a very simple View Controller based on google's example code and Im finding I am getting a leak when the map loads. I believe the leak is in the SDK itself. Has anyone come across this problem and found a solution?
basic View Controller
//
// JRCViewController.m
// GoogleMapsInterface
//
// Created by Jake Cunningham on 15/01/2014.
// Copyright (c) 2014 Jake Cunningham. All rights reserved.
//
#import "JRCViewController.h"
@interface JRCViewController (){
BOOL firstLocationUpdate_;
GMSMapView *mapView;
}
@end
@implementation JRCViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.868
longitude:151.2086
zoom:6];
mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
[mapView addObserver:self
forKeyPath:@"myLocation"
options:NSKeyValueObservingOptionNew
context:NULL];
self.view = mapView;
dispatch_async(dispatch_get_main_queue(), ^{
mapView.myLocationEnabled = YES;
});
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if (!firstLocationUpdate_) {
// If the first location update has not yet been recieved, then jump to that
// location.
firstLocationUpdate_ = YES;
CLLocation *location = [change objectForKey:NSKeyValueChangeNewKey];
mapView.camera = [GMSCameraPosition cameraWithTarget:location.coordinate
zoom:14];
}
}
@end
Upvotes: 4
Views: 1633
Reputation: 13947
I found the reason for the problem. Like you, I thought that their "demo code" was supposed to work as is. Not understanding that this line
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.868
longitude:151.2086
zoom:6];
The very first line in the demo was actually the problem. If you are not in Australia (which is where this location point is) You result in loading the entire world map (tiles) into the memory of the app, which is wrong!
If you know approximately which continent/country/state your map will be used or better yet! get the user's location BEFORE you show the map, and load the map at that location.
So your initialization of the map should be this:
CLLocation *location = [self getUserLocation]; //probably from shared prefs, even if its 100 miles away from where the user actually is, is better than loading another continent.
and then your viewDidLoad would look like this
- (void)viewDidLoad
{
[super viewDidLoad];
CLLocation *location = [self getUserLocation]; //<== very important!
// Do any additional setup after loading the view, typically from a nib.
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:location.coordinate.latitude
longitude:location.coordinate.longitude
zoom:15];
mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
[mapView addObserver:self
forKeyPath:@"myLocation"
options:NSKeyValueObservingOptionNew
context:NULL];
self.view = mapView;
dispatch_async(dispatch_get_main_queue(), ^{
mapView.myLocationEnabled = YES;
});
}
The zoom level also has an effect on this -> the bigger the zoom is, the less tiles you load into the memory.
also I added code in viewWillDisappear
(assuming that viewDidLoad
will run again when the given ViewController will be needed again)
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[self.mapView clear];
[self.mapView removeFromSuperview] ;
self.mapView.delegate = nil;
self.mapView = nil ;
}
This helped my app from having to use 140 MB of ram to just 56! When app normal is between 40 and 45.
Upvotes: 5