2

In my app I've got a UINavigationController.

In some of the pages I got a MKMapView as the back view (allows changes to map view the overlay UIView UI, so I can't make it as a image). In some combinations, It's possible to have 3 or so MKMapView alloc'd.

The problem is that each MKMapView takes nearly 60MB, so the memory jumps up to 180+ MB only from the maps. not to mention if the user opens more ViewControllers with map, he'll get a OutOfMemoryException.

All the maps have the same content, I tried moving a map from ViewController to another, but according to another post in StackOverflow, moving UIView from ViewController to another is against MVC, not to mention it removes it from the caller ViewController.

Basically since all the maps contains the same content, and I want them the contain all the annotations it'd be best to just move the map but I had hard time with that.

I've got a solution out of the box which is to remove the MKMapView from its superView and on viewWillAppear realloc it, but this doesn't seem like the best idea.

dmckee --- ex-moderator kitten
  • 98,632
  • 24
  • 142
  • 234
user2558461
  • 281
  • 1
  • 6
  • 21
  • I guess u are trying to load a new map view by retrieving users location and coordinates for each view controller...try using notifications in app delegate method and broadcast a message to all the objects when location updates this way u can reduce memory as well as code...u just need to set a listener object from the view controllers that need map data and don't forget to remove the listener in viewdiddisappear...if u haven't tried this method let me know I ll post you a sample code...happy coding! – bachman Dec 23 '13 at 00:48
  • Hi, less of code is nice, thank you for your suggestion, but still. I can get to OutOfMemory happily due to too many maps in memory. – user2558461 Dec 23 '13 at 01:06
  • @NiranjanRavichandran that doesn't save any noticeable amount of memory. What the OP is trying works.. – Daij-Djan Dec 23 '13 at 01:58

1 Answers1

2

I don't see any problem with passing a pointer to a single map view when you move from controller to controller. Unless you're viewing more than one map at a time, I don't see why there should be more that one instance. Remove the view in viewWillDisappear, and pass a pointer to the map in prepareForSegue:

- (void)viewDidLoad {
    [super viewDidLoad];
    if (! self.mapView) {
        self.mapView = [[MKMapView alloc] initWithFrame:self.view.frame];
    }
}


-(void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.view addSubview:self.mapView];
    [self.view sendSubviewToBack:self.mapView];
}

-(void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self.mapView removeFromSuperview];
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    SecondViewController *secVC = segue.destinationViewController;
    secVC.mapView = self.mapView;
}

Subsequent controllers could have the same code in viewWillAppear, viewWillDisappear, and prepareForSegue (except for what controller is the destinationViewController). The map only needs to be instantiated once in the viewDidLoad method of the first controller. An even simpler implementation would be to have all the subsequent view controllers inherit from the first controller. If you do it that way, you won't need to put anything in viewWillAppear or viewWillDisappear. You only need to override prepareForSegue.

rdelmar
  • 103,982
  • 12
  • 207
  • 218
  • i did a thing like this and it works ok with **maps that have the 100% same content** You get LOTS of issues if content differs! (Im aware OP mentioned the content of all the maps is equal. just a word of caution :) – Daij-Djan Dec 23 '13 at 01:56
  • @Daij-Djan, Yes, of course, good point. This method wouldn't work if you want differences, since you're just passing around a pointer to one object. – rdelmar Dec 23 '13 at 01:58