我有这个功能:
- (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
阻止线程直到将完成。我想将图片加载块添加到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块中使用上下文操作?
答案 0 :(得分:4)
我的第一个注意事项是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中:你绘制了可用的图块,并跳过那些没有的图块。