CATiledLayer多次请求相同的磁贴

时间:2011-04-03 17:49:24

标签: iphone cocoa-touch ios catiledlayer

请参阅此简单的CATiledLayer示例https://github.com/seanhess/CATiledLayer-Example

它由一个viewController组成,其层次结构如下:

view: (frame = window size)
    scrollView: (frame = window size, content size = 200 x 4000)
        contentView: (frame = content size = 200 x 4000, tile size = 100 x 100)

内容视图的图层已被覆盖为CATiledLayer。

如果您运行链接代码,您会看到多次请求具有相同rect的切片。它在您第一次运行代码和滚动时都会发生。

切换到分支“一列” - 它只发生在init上,永远不会向下滚动。

切换到分支“default-tile-size” - 它只发生在init上,但非常罕见(你必须在它发生之前多次运行)

我正在尝试在drawLayer:inContext:中编写一些代码来找到正确的数据并绘制它。它可能很昂贵,而且我不想多做一次。

知道发生了什么事吗?我能做些什么不同的事情?

5 个答案:

答案 0 :(得分:2)

这是IOS中的一个错误。它发生在CPU是双核的时候,在这种情况下,每个都有两个线程请求每个磁贴。这意味着该错误存在于模拟器和iPhone 4S上,但不存在于其他iPhone型号上。我认为它也将出现在双核iPad上。

我早就已经向Apple报告了这个错误(对于模拟器),最近又报告了(对于iPhone 4S)。 Apple最近给人的印象是他们已经在IOS 6中解决了它。

答案 1 :(得分:1)

在这里很好地解决了:

https://stackoverflow.com/a/8783396/341994

问题是(至少在我的测试中)drawRect:在两个线程上同时被调用。通过记录,我可以看到我的代码的各行在执行下一行之前执行了两次,这也执行了两次!日志记录显示这是因为一个线程正在执行一行,然后另一个线程正在执行同一行 - 然后它们都继续到下一行。

这是令人讨厌的。解决方案是将drawRect:的整个内部包装在串行队列的dispatch_sync中。

答案 2 :(得分:0)

您是否在设备上尝试过代码?我一直在模拟器中看到这种行为,但在我的iPad上却没有。我只是在一个显示大平铺图像的应用程序中再试一次。我的磁贴大小为256,在设备上我的drawRect:方法被调用12次,这是屏幕上有多少个磁贴。在模拟器中,该方法被调用20到23次,除了最后几个图块之外的所有图块被绘制两次。

答案 3 :(得分:0)

这不是setLevelsOfDetailBias的原因吗?当我将一切标准化时,瓷砖只会渲染一次(在设备上进行测试)。但是当我将levelofdetailbias设置为2时,tile会多次加载。我认为这是因为CATiledLayer在设备空闲时才开始缓存额外的细节级别。

答案 4 :(得分:0)

最后,答案没有用。但是,让你的委托方法知道它是否已经绘制了这个循环是相当简单的。