简体   繁体   中英

How to observe the dealloc process

In my app I'm downloading the location data and showing them on the map. There are some scenarios which I cannot understand why they are happening. Sometimes, my mapView(Google map) class dealloc is getting called and I'm unable to see the markers on my map(I can still see my current location).

This is how my mapView is setUp in the storyBoard:

 [ContainerVc] -embedSegue->[MapView]

Container Vc is the root Vc.

and in my rootVc class:

   @property (weak, nonatomic) MapVc *mapVc;

   - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if ([[segue identifier] isEqualToString: @"embeddedMapVc"]) {
        self.mapVc = [segue destinationViewController];
        self.mapVc.delegate = self;
    }
  }

and in my mapVC class(all the properties are strong,nonatomic):

  -(void)viewDidAppear:(BOOL)animated{
       [super viewDidAppear:animated];
       [self setupMapView];
  }

- (void)setupMapView{

    MyLog(@"Map view just refreshed/setup");
    //set map view
    self.infoWindow = [[MyMapInfoWindow alloc] initWithFrame:CGRectMake(0, 0, 210, 47)];
    self.infoWindow.delegate = self;


    CLLocation *center = [[MyLocationMonitor sharedInstance] getLocation];

    GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:center.coordinate.latitude longitude:center.coordinate.longitude zoom:18];

    self.mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
    self.mapView.camera=camera;
    [self.mapView setMapType:kGMSTypeNormal];
    [self.mapView setMinZoom:14 maxZoom:18];
    [self.mapView setDelegate:self];
    self.mapView.myLocationEnabled=YES;
    self.mapView.settings.rotateGestures = NO;
    self.mapView.settings.myLocationButton = YES;
    [self.mapView setPadding:UIEdgeInsetsMake(0, 0, 62, 0)];

    self.view = self.mapView;
    [self setupMarkers];

}

- (void)setupMarkers{
 MyLog(@"setting up markers");
 self.annotations = nil;
 [self.mapView clear];

 [[MyLocationMonitor sharedInstance] getBuildingsWithCompletion:^(BOOL success, NSArray *buildings) {
     self.buildings = buildings;
     MyLog(@"_buildings_: %@", self.buildings);
     if (success) {

         GMSCoordinateBounds  *bounds =  [[GMSCoordinateBounds alloc] init];

         self.annotations = [[NSMutableArray alloc] init];

         for (NSDictionary *location in buildings) {

             CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake([[location objectForKey:@"Latitude"] doubleValue], [[location objectForKey:@"Longitude"] doubleValue]);

             bounds = [bounds includingCoordinate:coordinate];

             GMSMarker *marker = [GMSMarker markerWithPosition:coordinate];
             marker.title = [location objectForKey:@"name"];
             marker.map = self.mapView;
             marker.icon = [UIImage imageNamed:@"Boost-BuildingMarkerIcon"];
             marker.userData = @{@"building":location};
             marker.infoWindowAnchor = CGPointMake(1.0f, -0.1f);
             marker.opacity = 1.0;

             [self.annotations addObject:marker];
         }
         [self.mapView animateWithCameraUpdate:[GMSCameraUpdate fitBounds:bounds withPadding:50.0]];

     }

 }];
 }

 -(void)dealloc{
  MyLog(@"MApVC dealloc called");
 }

So, from the rootVc I move to another controller and after I finish a network call I comeback to rootVc, where the prepareForSegue gets triggered and the call goes to mapVc class, and it setups the mapView(In this process mapVc dealloc gets called sometimes in that case, I'm unable to see the markers on the map).

在此处输入图片说明

I couldn't get much info from stacktrace. I would like to know why my mapVc is getting deallocated sometimes ? How to make sure my mapVc is not deallocated at any time ?

Edit:

I logged the mapVc self in the dealloc case:

 <MapVc: 0x7ff83f2883c0> On didAppear

<MapVc: 0x7ff83f2883c0> on dealloc (why is this happening ?)

<MapVc: 0x7ff84475b6f0> new instance again on viewDidAppear

How to make sure my mapVc is not deallocated at any time ?

If you require a VC to exist at a time when it is not onscreen (or at least in a navigation stack), then you have broken MVC. I don't think that's quite what's happening here, but it's important to keep in mind. Network operations should happen in your Model layer, and your view layer should observe the model. View controllers are responsible for managing views that are currently visible, not network operations. You likely have organized your view controllers incorrectly.

That said, that probably isn't the actual problem in this case. The problem is that nothing is retaining mapVc . It's weak in the root view controller so it's probably being released as soon as the segue is complete (the segue retains it while it is running). If mapVc is embedded in the root view controller, it should almost certainly be strong .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM