Domanda

I'm using a subclassed MKOverlay and subclassed MKOverlayView to display WMS tiles. Got it running well.

I'm running into the issue of removing the MKOverlayView when I'm done displaying the tiles. I can remove the MKOverlay just fine:

-(void)removeWMSOverlay {    
    for (WMSOverlay *overlay in self.mapView.overlays) {
        if ([overlay isKindOfClass:[WMSOverlay class]]) {            
            MKOverlayView *test = [self.mapView viewForOverlay:overlay];

            [self.mapView removeOverlay:overlay];
        }
    }
}

But the WMSOverlayView is still there and still running its code (constantly checking if new tiles can be draw) which creates some lag.

I don't know where to find a list of MKOverlayViews that are active. I tried:

-(void)removeWMSOverlay {    
    for (WMSOverlay *overlay in self.mapView.overlays) {
        if ([overlay isKindOfClass:[WMSOverlay class]]) {            
            MKOverlayView *test = [self.mapView viewForOverlay:overlay];

            [self.mapView removeOverlay:overlay];

            [test removeFromSuperview];

            test = nil;
        }
    }
}

to no effect. The code is still running.

Even tried to keep a reference of it around to nil:

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay {
    if ([overlay isKindOfClass:[WMSOverlay class]]) {

        WMSOverlayView *view = [[WMSOverlayView alloc] initWithOverlay:overlay];
        view.alpha = .8;

        self.wmsOverlayView = view;

        return view;
    }

    return FALSE;
}

-(void)removeScene {    
    for (WMSOverlay *overlay in self.mapView.overlays) {
        if ([overlay isKindOfClass:[WMSOverlay class]]) {            
            [self.mapView removeOverlay:overlay];

            self.wmsOverlayView = nil;
        }
    }
}

Can I remove the MKOverlayView or do I need to figure out how to reuse the view?

EDIT:

I tried reusing the MKOverlayView:

else if ([overlay isKindOfClass:[WMSOverlay class]]) {
    self.wmsOverlayView = [[WMSOverlayView alloc] initWithOverlay:overlay];

    return self.wmsOverlayView;
}

and added a timer to show that more then one MKOverLayView is runing:

-(void)amIStillHere {
    DLog("I'M STILL RUNNING | self: %@", self);
}

They don't get reused or go away:

 DEBUG | -[WMSOverlayView startTimer] | I'M STILL RUNNING | self: <WMSOverlayView: 0x1d84afe0; frame = (6.02801e+07 9.44092e+07; 2.30324e+06 2.10344e+06); opaque = NO; layer = <MKOverlayClusterProxyLayer: 0x21bf3ff0>>
 DEBUG | -[WMSOverlayView startTimer] | I'M STILL RUNNING | self: <WMSOverlayView: 0x21be1a80; frame = (6.06487e+07 9.2838e+07; 2.36776e+06 2.15038e+06); opaque = NO; layer = <MKOverlayClusterProxyLayer: 0x1d8e2a20>>
È stato utile?

Soluzione

Curious, I added the NSCacheDelegate to see when an item is evicted (I was concerned about having a NSCache for each WMSOverlayView and how they would behave and memory usage, I set the cache to 32mb and don't want to gobble up all memory). I tried naming each cache so I could see if there were two caches, I could see if the old cache was cleared out to make room in the memory for the newer cache. Realized each cache was always named the same:

-(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay {
    if (self.wmsOverlayView == nil) {
        self.wmsOverlayView = [[WMSOverlayView alloc] initWithOverlay:overlay withCacheName:@"CACHE!"];
    }
    else {
        self.wmsOverlayView = [[WMSOverlayView alloc] initWithOverlay:overlay withCacheName:@"THE NEW BETTER CACHE!"];
    }

    return self.wmsOverlayView;
}

I also noticed that self.wmsOverlayView was always nil and always naming the cache CACHE!. So the wmsOverlayView does get removed when the overlay is removed. But my timer kept going off. So I refactored my code to remove the timer and when I removed the WMSOverlay, the cache was cleared out (got my cache:willEvictObject: NSLog spammed).

So I believe the timer was keeping the WMSOverlayView alive.

Moral of the story: don't place a timer in a MKOverlayView.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top