我正在使用自定义MKOverlay/MKOverlayView
使用我自己的磁贴完全覆盖Google底图,这些磁贴是异步加载的。当我收到对我的覆盖视图的canDrawMapRect:zoomScale:
调用(并在这种情况下返回FALSE)时,我遵循请求卸载的切片的模式,然后在切片可用时调用setNeedsDisplayInMapRect:zoomScale:
。
这一切通常都有效,并且似乎在模拟器中完美运行。
但是,在设备上我有时会在叠加层中出现一个“洞” - 缺少一块瓦片。
我可以看到请求了磁贴,并且请求完成了。我可以看到我致电setNeedsDisplayInMapRect:zoomScale:
,并且我正在传递MKMapRect
中提供的原始MKZoomScale
和canDrawMapRect:zoomScale:
。但是我也可以看到覆盖层永远不会被要求重绘那个图块({4}}和canDrawMapRect:zoomScale:
都不再被称为该图块。
我需要了解为什么会发生这种情况以及如何纠正它。
以下是我的MKOverlayView子类中的相关代码:
drawMapRect:zoomScale:inContext:
答案 0 :(得分:1)
我遇到的问题与此处描述的问题非常相似。在我的情况下,我无法重现所需的行为(在http://developer.apple.com/library/ios/documentation/MapKit/Reference/MKOverlayView_class/Reference/Reference.html#//apple_ref/occ/instm/MKOverlayView/setNeedsDisplayInMapRect:zoomScale :)中描述,即使有最简单的代码:
- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale {
NSLog(@"This should trace forever");
[self setNeedsDisplayInMapRect:mapRect zoomScale:zoomScale];
return NO;
}
或更接近原始代码:
- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale {
NSLog(@"This should trace forever");
[SomeAsynchronousRequestWithCompletionHandler:^{
[self setNeedsDisplayInMapRect:mapRect zoomScale:zoomScale];
}];
return NO;
}
在这两种情况下, setNeedsDisplayInMapRect:zoomScale:从未被调用过一次。
情况发生了变化,当我开始在dispatch_async中运行 setNeedsDisplayInMapRect:zoomScale:时,调度到canDrawMapRect运行的同一队列,如:
- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale {
dispatch_queue_t queue = dispatch_get_current_queue();
NSLog(@"This should trace forever");
dispatch_async(queue, ^{
[self setNeedsDisplayInMapRect:mapRect zoomScale:zoomScale];
});
return NO;
}
或包含异步作业:
- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale {
NSLog(@"This should trace forever");
dispatch_queue_t queue = dispatch_get_current_queue();
[SomeAsynchronousRequestWithCompletionHandler:^{
dispatch_async(queue, ^{
[self setNeedsDisplayInMapRect:mapRect zoomScale:zoomScale];
});
}];
return NO;
}
使用dispatch_async - 我可以看到“这应该永远跟踪”字符串被无休止地跟踪。我原来的问题也完全消失了。
稍后更新:目前,我使用dispatch_get_main_queue()来调用 setNeedsDisplayInMapRect:zoomScale:,如
- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale {
NSLog(@"This should trace forever");
[SomeAsynchronousRequestWithCompletionHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
[self setNeedsDisplayInMapRect:mapRect zoomScale:zoomScale];
});
}];
return NO;
}
答案 1 :(得分:0)
上面的答案对我不起作用。从我使用的NSLog打印输出中我可以看到,虽然在canDrawMapRect中抓取dispatch_get_current_queue()并将其存储以供以后使用,但仍然使用了不同的线程。至少在iPad 4.3模拟器中就是这种情况,我没有尝试使用该设备。
在解决之前,我的解决方案不太令人满意且更容易出错等待x时间的解决方案。
-(void)setNeedsDisplay:(WebRequest*)webRequest
{
[webRequest retain];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.25 * NSEC_PER_SEC), dispatch_get_main_queue(),
^{
[webRequest autorelease];
[delegate setNeedsDisplayInMapRect:webRequest.request.requestedMapRect
zoomScale:webRequest.request.requestedScale];
});
}