gpt4 book ai didi

ios5: drawRect 在 CATiledLayer 中为同一个 Rect 调用了两次

转载 作者:行者123 更新时间:2023-11-29 13:44:48 25 4
gpt4 key购买 nike

我对 CATiledLayer 有疑问。它在 iOS 4 上运行完美,但在 iOS 5 上有问题。

我的问题是 drawRect 同时从两个不同的线程为同一个矩形调用两次。由于我在此调用中加载图像,因此导致 View 加载速度非常慢。

2011-10-18 14:07:18.802 APP[12436:19003] drawRect:{{0, 400}, {368, 400}} (view:<TiledScrollColumn: 0x91bc880; frame = (0 1600; 368 5400); userInteractionEnabled = NO; layer = <CATiledLayer: 0x919c1b0>>)
2011-10-18 14:07:18.805 APP[12436:1b103] drawRect:{{0, 400}, {368, 400}} (view:<TiledScrollColumn: 0x91bc880; frame = (0 1600; 368 5400); userInteractionEnabled = NO; layer = <CATiledLayer: 0x919c1b0>>)

有谁知道是什么原因导致的,或者我可以做些什么来解决这个问题?我没有对 View 做任何特殊的事情,它基于 photoscroller 示例。

巴斯蒂安

最佳答案

我找到了解决方法。创建一个串行(一次只有一个操作)调度队列并在其中执行所有绘图,然后缓存结果。

我附上了我正在使用的代码,注意我使用的是 CATiledLayer 的子类,而不是通过委托(delegate)或其他技术绘制它。

我还创建了一个不确定的切片缓存,这可能会导致内存问题,具体取决于您的情况。您可能需要管理缓存中的切片数量,在添加新切片时删除旧切片。当收到低内存警告时,缓存也应该被清除。如果有人添加这些改进,请随时编辑我的答案以包含它。

- (id)init
{
if (!(self = [super init]))
return nil;

tileCache = [[NSMutableDictionary alloc] init];

return self;
}

- (void)drawInContext:(CGContextRef)layerContext
{
// CATiledLayer has a bug, where it spawns multiple threads for drawing, and then tries to draw the same tile multiple times simultaniously on separate threads
// so we create our own serial background queue, and do dispatch_async on it. This will cache each draw operation, so multiple calls on one tile are efficient
static dispatch_queue_t drawQueue = NULL;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
drawQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
});

dispatch_sync(drawQueue, ^{

// no map ways? draw nothing
if (!self.mapWays)
return;

// load from cache?
CGRect tileRect = CGContextGetClipBoundingBox(layerContext);
NSString *tileCacheKey = [NSString stringWithFormat:@"%f%f%f%f", tileRect.origin.x, tileRect.origin.y, tileRect.size.width, tileRect.size.height];
__block UIImage *tileImage;
dispatch_sync(dispatch_get_main_queue(), ^{
tileImage = [tileCache objectForKey:tileCacheKey];
});
if (tileImage) {
CGContextDrawImage(layerContext, tileRect, tileImage.CGImage);
return;
}

// prepare to draw the tile image
UIGraphicsBeginImageContextWithOptions(tileRect.size, YES, 0);
CGContextRef context = UIGraphicsGetCurrentContext();

// filp coords
CGContextTranslateCTM(context, 0, tileRect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);


/*** do actual drawing here ***/


// store tile in cache
tileImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
dispatch_sync(dispatch_get_main_queue(), ^{
[tileCache setObject:tileImage forKey:tileCacheKey];
});

// draw the tile
CGContextDrawImage(layerContext, tileRect, tileImage.CGImage);
});
}

关于ios5: drawRect 在 CATiledLayer 中为同一个 Rect 调用了两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7807193/

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