MapKit with MKTileOverlay Crashes After a Time

I'm building a weather map that shows the rain on the map. I'm able to retrieve PNG images that are used as tiles to put onto the map. I then reload all the tiles on the map with each timeframe (tile set for every 10 minutes).

I'm able to get the map loaded up and I'm able to place the tiles and reload the data for each time slot. I preload all the PNG data needed for the tiles and store that NSData for them in memory so that they are quick for loading and showing on the map.

I have timer's set to reload the overlay with the next set of tiles for each time slot. Giving the view of a moving precipitation map over time (just like you'd see on any weather map.)

I have 12 time slots (timestamps) showing every 10 minutes for the past 2 hours. I have it showing each in sequence and then repeating.

Over time I get a crash with this error as a Thread 1: ****** SIGABRT.

Failed to acquire drawable, rendering to temporary texture
validateRenderPassDescriptor:782: failed assertion `RenderPass Descriptor Validation
MTLRenderPassAttachmentDescriptor MTLStoreActionMultisampleResolve store action at attachment 0 requires resolve texture
'
validateRenderPassDescriptor:782: failed assertion `RenderPass Descriptor Validation
MTLRenderPassAttachmentDescriptor MTLStoreActionMultisampleResolve store action at attachment 0 requires resolve texture
'

Through some searching I've discovered that this seems to be console output from Metal. I assume Metal is used for MapKit to render the overlay tiles?

I'm using the same custom overlay where I set the timestamp on it and then tell it to reload. I also reuse the same MKOverlayRenderer as shown here...

- (MKOverlayRenderer*)mapView:(MKMapView*)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
if ([overlay isKindOfClass:[MKTileOverlay class]]) {
if (!self.rainRenderer) {
self.rainRenderer = [[MKTileOverlayRenderer alloc] initWithTileOverlay:overlay];
self.rainRenderer.alpha = 0.5;
}
return self.rainRenderer;
}
return nil;
}

And here's the function that reloads the overlay...

- (void) updateRainFrame {
self.currentFrameIndex = (self.currentFrameIndex + 1) % self.timestamps.count;
if ((self.currentFrameIndex >= 0) && (self.timestamps.count > self.currentFrameIndex)) {
NSLog (@"self.currentFrameIndex = %lu", self.currentFrameIndex);
NSString *timestamp = self.timestamps[self.currentFrameIndex];
[self.overlay setTimestamp:timestamp];
[self.rainRenderer reloadData];
}
}

The time it takes to crash seems arbitrary. Sometimes it's very quick. Less than a minute. But usually it's several minutes. 10 or 20 minutes or more. Feels like some sort of race condition that's occurring. Perhaps ARC is not able to release the images for the tiles quick enough for each overlay reload? That's a wild guess but I think it's something more deeper in Metal as I feel I would see other errors related to memory availability.

Some of my searches point to something about MSAA needing to be turned off in Metal to resolve this. However I have no idea how I would do that through MapKit.

Any suggestions? Let me know if there is somehow a way to capture more from the crash to give more insight.

I've done some more experimenting. I'm now creating overlays for each timestamp (12 of them) along with the renderers. I then set all renderer alpha to 0 except the one which overlay I want to show at that moment which I set to 0.5 alpha. Then I just cycle through the overlays setting their renderer's alpha. Makes for a very smooth animation.

Then every minute I reload the data, remove all the overlays, and create new ones with the new data. In production I'd do this every 10 minutes but to test this I do it every 60 seconds.

This bug is still coming up. Again it takes about 20 to 60 minutes for it to occur.

I then tried removing the MapView from its superview and remove all the overlays, and the delegate. I can confirm it is removed by monitoring the memory usage. I then create a new MapView and add it to my ViewController's view as a subView and then remake all the overlays for that new mapView. Memory usage is stable over the testing period. I figured this would clear out any issue with Metal holding on to things. But after about an hour. Same issue.

I'm not sure how to proceed now. This is really starting to seem like a bug? I hate to point at that as the issue but I'm at a loss what to do next?

I snagged two captures of the gpu debug screen. The numbers on the right I'm not certain what they mean but hoping that might point to something?

First, is the image of the GPU hud when I first start things going.

Next is the image when the app crashes.

Hi there, thank you for posting the question. Our engineering teams need to investigate this issue, as resolution may involve changes to Apple's software. I'd greatly appreciate it if you could open a bug report, please post the FB number here once you do.

Bug Reporting: How and Why? has tips on creating your bug report.

At the same time, do you get the same results with just the relevant code in a small test project? If so, please share a link to your test project. That'll help us better understand what's going on. If you're not familiar with preparing a test project, take a look at Creating a test project.

MapKit with MKTileOverlay Crashes After a Time
 
 
Q