gpt4 book ai didi

ios - setNeedsDisplayInMapRect 不触发新的 drawMapRect : call

转载 作者:可可西里 更新时间:2023-11-01 03:20:08 24 4
gpt4 key购买 nike

我正在使用自定义 MKOverlay/MKOverlayView 用我自己的异步加载的图 block 完全覆盖 Google basemap 。当我收到对覆盖 View 的 canDrawMapRect:zoomScale: 调用(并在这种情况下返回 FALSE)时,我遵循请求卸载图 block 的模式,然后调用 setNeedsDisplayInMapRect:zoomScale:一旦瓷砖可用。

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

但是,在设备上,我有时会在叠加层中看到一个“洞”——缺失的图 block 。

我可以看到该图 block 已被请求,并且请求已完成。我可以看到我调用了 setNeedsDisplayInMapRect:zoomScale:,并且我正在传递 canDrawMapRect 中提供的原始 MKMapRectMKZoomScale :缩放比例:。但我也可以看到,从未要求叠加层重绘该图 block (canDrawMapRect:zoomScale:drawMapRect:zoomScale:inContext: 都不再为该图 block 调用) .

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

这是我的 MKOverlayView 子类的相关代码:

- (BOOL) canDrawMapRect: (MKMapRect) mapRect zoomScale: (MKZoomScale) zoomScale 
{
NSUInteger zoomLevel = [self zoomLevelForZoomScale:zoomScale];
CGPoint mercatorPoint = [self mercatorTileOriginForMapRect:mapRect];
NSUInteger tilex = floor(mercatorPoint.x * [self worldTileWidthForZoomLevel:zoomLevel]);
NSUInteger tiley = floor(mercatorPoint.y * [self worldTileWidthForZoomLevel:zoomLevel]);

NSURL* tileUrl = [self tileURLForZoomLevel: zoomLevel tileX: tilex tileY: tiley];

ASIHTTPRequest* tileRequest = [ASIHTTPRequest requestWithURL: tileUrl];
tileRequest.downloadCache = [ASIDownloadCache sharedCache];
[tileRequest setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];

if ( NO == [[ASIDownloadCache sharedCache] isCachedDataCurrentForRequest: tileRequest] )
{
[tileRequest setCachePolicy: ASIAskServerIfModifiedWhenStaleCachePolicy];
tileRequest.delegate = self;
tileRequest.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
[NSValue value: &mapRect withObjCType: @encode( MKMapRect )], @"mapRect",
[NSValue value: &zoomScale withObjCType: @encode( MKZoomScale )], @"zoomScale",
[NSNumber numberWithInt: tilex], @"tilex",
[NSNumber numberWithInt: tiley], @"tiley",
nil];

[_tileRequestStack addOperation: tileRequest];

NSLog( @"canDrawMapRect: %d, %d - REQUESTING", tilex, tiley );

return NO;
}

NSLog( @"canDrawMapRect: %d, %d - READY", tilex, tiley );

return YES;
}

- (void) drawMapRect: (MKMapRect) mapRect zoomScale: (MKZoomScale) zoomScale inContext: (CGContextRef) context
{
NSUInteger zoomLevel = [self zoomLevelForZoomScale:zoomScale];

CGPoint mercatorPoint = [self mercatorTileOriginForMapRect:mapRect];

NSUInteger tilex = floor(mercatorPoint.x * [self worldTileWidthForZoomLevel:zoomLevel]);
NSUInteger tiley = floor(mercatorPoint.y * [self worldTileWidthForZoomLevel:zoomLevel]);

NSLog( @"drawMapRect: %d, %d", tilex, tiley );

NSURL* tileUrl = [self tileURLForZoomLevel: zoomLevel tileX: tilex tileY: tiley];
NSData* tileData = [[ASIDownloadCache sharedCache] cachedResponseDataForURL: tileUrl];

UIGraphicsPushContext(context);

if ( tileData != nil )
{
UIImage* img = [UIImage imageWithData: tileData];

if ( img != nil )
{
[img drawInRect: [self rectForMapRect: mapRect] blendMode: kCGBlendModeNormal alpha: 1.0 ];
}
else
{
NSLog( @"oops - no image" );
}

CGSize s = CGContextConvertSizeToUserSpace( context, CGSizeMake( 40, 1 ));

UIFont* f = [UIFont systemFontOfSize: s.width];

[[UIColor blackColor] setFill];

[[NSString stringWithFormat: @"%d,%d", tilex, tiley] drawInRect: [self rectForMapRect: mapRect] withFont: f];
}

UIGraphicsPopContext();
}


- (void) requestFinished: (ASIHTTPRequest *) tileRequest
{
NSValue* mapRectValue = [tileRequest.userInfo objectForKey: @"mapRect"];
MKMapRect mapRect; [mapRectValue getValue: &mapRect];

NSValue *zoomScaleValue = [tileRequest.userInfo objectForKey:@"zoomScale"];
MKZoomScale zoomScale; [zoomScaleValue getValue: &zoomScale];

NSLog( @"requestFinished: %d, %d, %lf",
[[tileRequest.userInfo objectForKey:@"tilex"] intValue],
[[tileRequest.userInfo objectForKey:@"tiley"] intValue],
zoomScale );

[self setNeedsDisplayInMapRect: mapRect zoomScale: zoomScale];
}

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

最佳答案

我遇到的问题与此处描述的问题非常相似。在我的例子中,我无法重现所需的行为(在 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: 时,dispatch_async 被调度到 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 - 我可以看到 “This should trace forever” 字符串被无休止地跟踪。我原来的问题也完全消失了。

稍后更新:目前,我使用 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;
}

关于ios - setNeedsDisplayInMapRect 不触发新的 drawMapRect : call,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10128447/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com