gpt4 book ai didi

ios - drawMapRect 上下文 + Grand Central Dispatch

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:47:27 26 4
gpt4 key购买 nike

我有这个功能:

- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
{
TileOverlay *tileOverlay = (TileOverlay *)self.overlay;
NSArray *tilesInRect = [tileOverlay tilesInMapRect:mapRect zoomScale:zoomScale];
CGContextSetAlpha(context, tileAlpha);

for (ImageTile *tile in tilesInRect)
{
__block UIImage * image;
CGRect rect = [self rectForMapRect:tile.frame];

NSString *path = [[NSString alloc] initWithFormat:@".../%@.png", tile.imagePath];
NSLog(@"Loading tile from URL %@", path);
image =[UIImage imageWithData: [NSData dataWithContentsOfURL:[NSURL URLWithString: path]]];

CGContextSaveGState(context);
CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect));
CGContextScaleCTM(context, 1/zoomScale, 1/zoomScale);
CGContextTranslateCTM(context, 0, image.size.height);
CGContextScaleCTM(context, 1, -1);
CGContextDrawImage(context, CGRectMake(0, 0, image.size.width, image.size.height), [image CGImage]);
CGContextRestoreGState(context);
}
}

如您所知,dataWithContentsOfURL 阻塞线程直到完成。我想将图像加载 block 添加到 GCD 部分。

我试着这样做:

- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
{
TileOverlay *tileOverlay = (TileOverlay *)self.overlay;
NSArray *tilesInRect = [tileOverlay tilesInMapRect:mapRect zoomScale:zoomScale];
CGContextSetAlpha(context, tileAlpha);

for (ImageTile *tile in tilesInRect)
{
__block UIImage * image;
CGRect rect = [self rectForMapRect:tile.frame];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{
NSString *path = [[NSString alloc] initWithFormat:@".../%@.png", tile.imagePath];
NSLog(@"Loading tile from URL %@", path);
image =[UIImage imageWithData: [NSData dataWithContentsOfURL:[NSURL URLWithString: path]]];

CGContextSaveGState(context);
CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect));
CGContextScaleCTM(context, 1/zoomScale, 1/zoomScale);
CGContextTranslateCTM(context, 0, image.size.height);
CGContextScaleCTM(context, 1, -1);
CGContextDrawImage(context, CGRectMake(0, 0, image.size.width, image.size.height), [image CGImage]);
CGContextRestoreGState(context);
});
}
}

但是我遇到了上下文错误。请帮我解决这些问题。如何在GCD block 中使用上下文操作?

最佳答案

我的第一个注意事项是 MKOverlayView 已贬值。您应该考虑切换到 MKOverlayRenderer。

在任何情况下都不应在 -draw__ 方法中使用 GCD。这包括 MKOverlayView -drawMapRect:zoomScale:inContext: 以及 UIView -drawRect:。相反,您应该将 NSOperationQueue 与 -canDrawMapRect:zoomScale:zoomScale 和 setNeedsDisplayInMapRect: 结合使用。

这是它的一些 sudo 代码:

- (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale
{
BOOL hasAtLeastOneTile = NO;
TileOverlay *tileOverlay = (TileOverlay *)self.overlay;
NSArray *tilesInRect = [tileOverlay tilesInMapRect:mapRect zoomScale:zoomScale];

for (ImageTile *tile in tilesInRect) {
if ([tile isAvailable]) {
hasAtLeastOneTile = hasAtLeastOneTile || YES;
} else {
// Add operation to NSOperationQueue to fetch tile
__weak MKOverlayView *weakOverlay = self; // Weak ref to prevent retain cycles
NSOperation *op = [NSBlockOperation blockOperationWithBlock: ^{
//TODO: Load Tile
[weakOverlay setNeedsDisplayInMapRect:mapRect];
}];
[self.operationQueue addOperation:op];
}
}
return hasAtLeastOneTile;
}

然后在您的 -drawMapRect:zoomScale:inContext: 中绘制可用的图 block 并跳过不可用的图 block 。

关于ios - drawMapRect 上下文 + Grand Central Dispatch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19449654/

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