iPad 视网膜模拟器中的 CATiledLayer 性能不佳
Posted
技术标签:
【中文标题】iPad 视网膜模拟器中的 CATiledLayer 性能不佳【英文标题】:CATiledLayer in iPad retina simulator yields poor performance 【发布时间】:2012-03-30 07:37:32 【问题描述】:我希望这可能只是模拟器的一个问题,但当然这让我很担心,因为我已经提交了支持视网膜的应用程序,并且在 16 日之前无法对其进行测试。
我在我的应用中实现了一个 CATiledLayer 来查看非常大的地图。地图的瓦片来自互联网,但它们也会被缓存,因此通常它们实际上是直接从设备加载的。
在 iPad 1 和 iPad2 上运行良好。您几乎无法注意到 iPad 2 上正在渲染的图块,即使它们来自互联网。
在 iPad 模拟器上它运行良好。
我的问题是 iPad 视网膜模拟器。从视觉上看,它看起来还不错。地图大小合适,并与我用来显示数据叠加层的另一层对齐,但加载速度非常慢。在我尝试的大部分时间里,它根本不会加载任何图块,直到我开始滚动,然后当它正在加载图块时,它可能每秒加载 1 个图块,看起来很糟糕。
我没有在视网膜上运行与标准分辨率屏幕不同的代码,所以我希望这只是模拟器的问题......但我仍然担心。
有其他人在他们自己的应用中看到过这种情况吗?
【问题讨论】:
【参考方案1】:较大的图块尺寸对我来说有点用,但是当我调整 CATiledLayer 的 levelsOfDetailBias 属性时,它会重新制作小图块,并且需要永远加载。关闭细节偏差是不可接受的,因为放大视图需要看起来清晰,所以我查看了一些 Apple 的文档 - https://web.archive.org/web/20120323033735/http://developer.apple.com/library/ios/samplecode/ZoomingPDFViewer/Listings/Classes_PDFScrollView_m.html - 他们的建议之一是覆盖平铺视图的 layoutSubviews 方法以始终设置 contentScaleFactor = 1. 之后我唯一要做的就是在每次触发 scrollViewDidEndZooming 时调用 setNeedsLayout。这是假设您使用的是 UIScrollView。我已经在我的 iPad(第 3 代)和 iPad2 上对此进行了测试,两者似乎都运行良好。希望对您有所帮助。
示例代码 - 假设您正在继承 UIView 并使用 CATiledLayer 覆盖视图的支持层 -
-(void)layoutSubviews
[super layoutSubviews];
/*
EDIT: After some additional experimentation,
I Have found that you can modify this number to .5 but you need
to check to make sure you are working on a 3rd gen iPad. This
seems to improve performance even further.
*/
// Check if app is running on iPad 3rd Gen otherwise set contentScaleFactor to 1
self.contentScaleFactor = .5;
然后假设您的 View Controller 设置为 UIScrollViewDelegate -
-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
//do any other stuff you may need to do.
[view setNeedsLayout];
【讨论】:
我正在尝试这个,但我没有看到任何区别?这是否应该与将瓷砖加倍然后有效地否定视网膜显示具有相同的效果? 它告诉 iOS 像通常在非视网膜显示器上那样处理图块大小,而不是尝试缩放它们,尽管根据您的实现可能并非如此。您应该仔细检查的一件事是tilesize,您仍然需要将其提升到1024X1024,如果您正在显示的是PDF,渲染时间可能会根据PDF的大小和质量而有所不同。在我的实现中,某些 PDF 的打开速度比其他 PDF 更快并且平铺的更少,我仍在深入研究为什么会这样。如果您发布一些代码,我将非常乐意查看它。 这对我们不起作用。希望有人可以分享更多解决方案。 @mzider,您能否提供您在其中看到此建议的 Apple 文档的链接?谢谢! @Altealice 你可以在 ZoomingPDFViewer 示例中找到他们的建议 - bit.ly/JwA1YD 确切的引用是这样的 - "// 处理 CATiledLayer 和高分辨率屏幕之间的交互,我们需要手动设置 / / 将视图的 contentScaleFactor 平铺为 1.0。(如果我们省略了这个,在高分辨率屏幕上它将是 2.0,//这将导致 CATiledLayer 向我们询问比例错误的图块。) pdfView.contentScaleFactor = 1.0;"【参考方案2】:所有 TiledLayers 在 iPad3 上的性能都比在 iPad2 上差 - 这在 GoogleMaps 应用中也可见。
但是,通过将以下更改添加到使用 CATiledLayer 的 UIView 类,可以获得最佳性能
- (id)initWithFrame:(CGRect)frame tileSize:(CGSize)tileSize
self = [super initWithFrame:frame];
if(self)
CATiledLayer *animLayer = (CATiledLayer *) self.layer;
animLayer.levelsOfDetail = 5;
animLayer.levelsOfDetailBias = 3;
animLayer.tileSize = tileSize;
// adjustments for retina displays
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES && [[UIScreen mainScreen] scale] == 2.00)
animLayer.contentsScale = 1.0;
self.contentScaleFactor = .5;
animLayer.shouldRasterize = NO;
animLayer.levelsOfDetailBias ++;
return self;
- (void)layoutSubviews
[super layoutSubviews];
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES && [[UIScreen mainScreen] scale] == 2.00)
self.contentScaleFactor = .5;
还有其他选项可以在视觉上实现相同的结果,即增加 tileSize 但性能会更差。
【讨论】:
请注意我上面的评论:将 contentScaleFactor 设置为 .5 会导致图层以 iPad 2(非视网膜)分辨率进行渲染,这对我们许多人来说可能无法接受。【参考方案3】:模拟器上的 CATiledLayer 性能似乎与实际的新 iPad 上的性能完全不同。在实际硬件上进行测试。
CATiledLayer 在新 iPad 上生成的图块比在旧设备上多得多,即使使用相同的设置也是如此。目前我检测代码是否在招聘屏幕上运行(通过 CALayer 的 contentScale 属性),如果是,则设置更大的图块大小。
我会做更多的实验,并会在这里发布任何重要的发现。
【讨论】:
谢谢 - 我发现了同样的事情,我的应用程序的问题是它显示了 4 倍的图块。是的,它看起来很清晰,但是当普通用户将我的应用程序放在 iPad 1 旁边的 iPad 3 上并显示地图时 - iPad 1 在显示地图方面远远胜过 iPad 3。有没有办法在不修改平铺图像的情况下改变这种行为? (我有几十万块瓷砖)。 我认为您不需要修改平铺图像。当代码在高分辨率显示器上运行时,您可能只需要显式地将 CATiledLayer 上的 tileSize 属性设置为更大的尺寸。【参考方案4】:请记住,它只是一个模拟器,而且很可能是软件加速的。另一方面,该设备是硬件加速的,Core Animation 是高度优化的,因为只有很少的目标 GPU 可供寻找。
在您检查新 iPad 本身的性能之前,我不会关心模拟器的结果。
【讨论】:
我有一个ipad3,你应该担心。性能明显变差。 iPad 3 比模拟器好得多……但是是的,它似乎比 iPad 2 慢。以上是关于iPad 视网膜模拟器中的 CATiledLayer 性能不佳的主要内容,如果未能解决你的问题,请参考以下文章
JSONKit 崩溃:iPad 视网膜 64 位设备模拟器中的 iOS 7 Xcode 5.1
带有 Tableview 图形的 iPad 2 模拟器上的问题仅影响非视网膜显示
更改 Xcode 4.3.2 的 iPad/iPhone 模拟器分辨率 [重复]