setNeedsDisplayInMapRect不会触发新的drawMapRect:call

时间:2012-04-12 17:11:54

标签: ios mkmapview mapkit mkoverlay

我正在使用自定义MKOverlay/MKOverlayView使用我自己的磁贴完全覆盖Google底图,这些磁贴是异步加载的。当我收到对我的覆盖视图的canDrawMapRect:zoomScale:调用(并在这种情况下返回FALSE)时,我遵循请求卸载的切片的模式,然后在切片可用时调用setNeedsDisplayInMapRect:zoomScale:

这一切通常都有效,并且似乎在模拟器中完美运行。

但是,在设备上我有时会在叠加层中出现一个“洞” - 缺少一块瓦片。

我可以看到请求了磁贴,并且请求完成了。我可以看到我致电setNeedsDisplayInMapRect:zoomScale:,并且我正在传递MKMapRect中提供的原始MKZoomScalecanDrawMapRect:zoomScale:。但是我也可以看到覆盖层永远不会被要求重绘那个图块({4}}和canDrawMapRect:zoomScale:都不再被称为该图块。

我需要了解为什么会发生这种情况以及如何纠正它。

以下是我的MKOverlayView子类中的相关代码:

drawMapRect:zoomScale:inContext:

编辑I'm guessing that this is likely the issue.

2 个答案:

答案 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];
   });     
}