-
Notifications
You must be signed in to change notification settings - Fork 8
Numerous duplicate URL tile requests #206
Description
It appears that if a tile is not already cached and must be requested it will often perform multiple URL requests for the same tile. I added an NSLog statement in the imageForTile:inCache: method in RMAbstractWebMapSource file:
NSHTTPURLResponse *response = nil;
NSLog(@"URL request: %@", [URLs objectAtIndex:0]);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[URLs objectAtIndex:0]];
[request setTimeoutInterval:(self.requestTimeoutSeconds / (CGFloat)self.retryCount)];
image = [UIImage imageWithData:[NSURLConnection sendBrandedSynchronousRequest:request returningResponse:&response error:nil]];
I will get multiple statements (sometimes 10 for same tile) in the console such as the following:
URL request: http://a.tiles.mapbox.com/v3/examples.map-z2effxa8/5/5/5.png
I tested this using the MabBox example (on iPad 6.0 simulator).
I traced the issue to RMMapTileLayerView. In the method drawLayer:inContext:
@synchronized ([(RMAbstractWebMapSource *)_tileSource URLForTile:RMTileMake(x, y, zoom)])
{
// this will return quicker if cached since above attempt, else block on fetch
//
if (_tileSource.isCacheable && [_tileSource imageForTile:RMTileMake(x, y, zoom) inCache:[_mapView tileCache]])
{
dispatch_async(dispatch_get_main_queue(), ^(void)
{
// do it all again for this tile, next time synchronously from cache
//
[self.layer setNeedsDisplayInRect:rect]; // <--- problem line
});
}
}
The setNeedsDisplayInRect call causes the drawLayer to be called numerous times for the same tile until it is actually downloaded and in the cache. Commenting out the setNeedsDisplayInRect fixes this problem and results in noticeable performance improvement (but may possibly result in other drawing issues in cases I am not aware of that this attempted to address to begin with).
What may be related: The URLForTile: method will return a new NSString object every time it is called even for the exact same tile so it is my understanding that the @synchronized call is more or less worthless in this instance.