【发布时间】:2010-06-27 03:40:41
【问题描述】:
这与另一篇文章有些相关——但那篇文章有点搞砸了——所以我从头开始:
我有一个 CATiledLayer,里面有一个巨大的图像 (5780x6700px)。
平铺层位于滚动视图中。当我开始滚动时,一切都很好,直到明显渲染了太多的瓷砖。然后我收到内存警告,应用程序崩溃。
当我收到内存警告时,我试图从视图中删除 tiledlayer,清除它的内容(rootLayer.contents = nil AND tiledLayer.contents = nil),然后将其重新附加到视图中。没用...
感谢您的任何意见...
编辑:
感谢到目前为止的提示。我的一些假设似乎是错误的。我将图像加载到一个函数中,然后保留它——我猜这与 CATiledLayer 的行为相矛盾。加上UIImage imageNamed: 似乎也引起了一些错误。
现在我将图像加载到drawLayer:(CALayer *) inContentext(CGContextRef) ctx 并使用UIImage imageWithContentsOfFile: 加载它。
这似乎可以正常工作而不会导致内存不足。
但是 - 瓷砖的绘制速度非常缓慢:(
这是我对 tiledLayer 的设置:
-(CATiledLayer *)initTiledLayers: (int)level{
//[tiledLayer release];
CGRect pageRect;
CATiledLayer *myLayer = [CATiledLayer layer];
myLayer.delegate = self;
if(level == 1){
pageRect = CGRectMake(0, 0, 690, 800);
myLayer.tileSize = CGSizeMake(800, 800);
myLayer.levelsOfDetail = 10;
myLayer.levelsOfDetailBias = 2;
}else if(level == 2){
pageRect = CGRectMake(0, 0, 1445, 1675);
myLayer.tileSize = CGSizeMake(600, 600);
myLayer.levelsOfDetail = 8;
myLayer.levelsOfDetailBias = 2;
}else if(level == 3){
pageRect = CGRectMake(0, 0, 2890, 3350);
myLayer.tileSize = CGSizeMake(400, 400);
myLayer.levelsOfDetail = 4;
myLayer.levelsOfDetailBias = 1;
}else if(level == 4){
pageRect = CGRectMake(0, 0, 5780, 6700);
myLayer.tileSize = CGSizeMake(150, 150);
myLayer.levelsOfDetail = 4;
myLayer.levelsOfDetailBias = 0;
}
myLayer.frame = pageRect;
return myLayer;
[myLayer release];
}
(int)level 指示要使用的图像(我在某些缩放级别上切换图像)。 Level4是最大的图像...
这里是drawLayer函数:
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{
CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0);
CGContextFillRect(ctx, CGContextGetClipBoundingBox(ctx));
CGContextTranslateCTM(ctx, 0.0, layer.bounds.size.height);
CGContextClearRect(ctx, CGRectMake(0,0,layer.bounds.size.width, layer.bounds.size.height));
CGContextScaleCTM(ctx, 1.0, -1.0);
UIImage *map = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"Karte0%d", actLevel] ofType:@"jpg"]];
UIImage *wanderwege = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"Karte0%d_wanderwege", actLevel] ofType:@"png"]];
UIImage *rhb = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"Karte0%d_rhb", actLevel] ofType:@"png"]];
UIImage *abstecher = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"Karte0%d_abstecher", actLevel] ofType:@"png"]];
CGRect imageRect = CGRectMake (0.0, 0.0, map.size.width, map.size.height);
CGContextDrawImage (ctx, imageRect, [map CGImage]);
imageRect = CGRectMake (0.0, 0.0, wanderwege.size.width, wanderwege.size.height);
CGContextDrawImage (ctx, imageRect, [wanderwege CGImage]);
imageRect = CGRectMake (0.0, 0.0, rhb.size.width, rhb.size.height);
CGContextDrawImage (ctx, imageRect, [rhb CGImage]);
imageRect = CGRectMake (0.0, 0.0, abstecher.size.width, abstecher.size.height);
CGContextDrawImage (ctx, imageRect, [abstecher CGImage]);
}
是的 - 我知道 - 我实际上在上下文中绘制了 4 张图像。 PNG 是我需要动态添加到主图像的叠加层...
我尝试将图像合并为一个 - 但这似乎更消耗内存/cpu ;)
非常感谢任何进一步的帮助!
【问题讨论】:
-
你能说得更具体一点吗?重置内容并重新附加时会发生什么?
-
你是如何加载图像的?
UIImage imageNamed有一些内存泄漏问题(我怀疑缓存确实过度,但无论如何净效果是一样的)。 -
@Ben:当我重新附加图层时,它是黑色的(似乎是 emtpy)。但是在绘制了前几个图块之后,内存警告又回来了。我尝试了从非常小到非常大的每个瓷砖尺寸。我还将 LOD 设置为 2 到 100。偏差设置为 0 到 2。@Dad - 我确实使用 UIImage imageNamed 进行加载 - 会试一试(虽然,我不确定我之前是否尝试过:)
标签: iphone memory-leaks catiledlayer