CATiledLayer 多次请求同一个图块

发布于 2024-10-29 05:33:15 字数 758 浏览 2 评论 0原文

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

它包括具有如下层次结构的一个视图控制器:

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。

如果您运行链接的代码,您将看到具有相同矩形的图块被多次请求。当您第一次运行代码和滚动时都会发生这种情况。

切换到分支“一列” - 它仅发生在 init 上,而不会在您向下滚动时发生。

切换到分支“default-tile-size” - 它只发生在 init 上,但很少发生(您必须在发生之前多次运行它)

我试图在 drawLayer:inContext:drawLayer:inContext: 找到正确的数据并绘制它。这可能会很昂贵,而且我不想重复这样做。

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

Please see this simple CATiledLayer example https://github.com/seanhess/CATiledLayer-Example

It consists of one viewController with a hierarchy like this:

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)

The content view's layer has been overriden to be a CATiledLayer.

If you run the linked code, you'll see that tiles with the same rect are requested multiple times. It happens both when you first run the code, and when you scroll.

Switch to branch "one-column" - it only happens on init, never when you scroll down.

Switch to branch "default-tile-size" - it only happens on init, but very rarely (you have to run it multiple times before it happens)

I'm trying to write some code in drawLayer:inContext: that locates the correct data and draws it. It could be expensive, and I don't want to do it more than once.

Any idea what is going on? What could I do differently?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

迷荒 2024-11-05 05:33:16

这里很好地解决了:

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

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

这真是太糟糕了。解决方案是将 drawRect: 的整个内部包装在串行队列上的 dispatch_sync 中。

Very well solved here:

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

The problem is that (at least in my testing) drawRect: is called simultaneously on two threads. By logging, I can see individual lines of my code being executed twice before we go on to the next line, which is also executed twice! The logging shows that this is because one thread is executing a line and then another thread is executing the same line - and then they both go on to the next line.

This is as nasty as it gets. The solution is to wrap the the whole interior of drawRect: in a dispatch_sync on a serial queue.

一瞬间的火花 2024-11-05 05:33:16

您是否在设备上尝试过代码?我一直在模拟器中看到这种行为,但在我的iPad 1上没有看到。我只是在显示大型瓷砖图像的应用程序中再次尝试过。我的瓷砖尺寸为256,在设备上我的绘制:方法被称为12次,这就是屏幕上有多少瓷砖。在模拟器中,该方法被调用20到23次,除了最后几个瓷砖两次,所有方法都被调用。

Have you tried your code on a device? I consistently see this behavior in the simulator, but not on my iPad 1. I just tried this again in an app that is displaying a large tiled image. My tile size is 256 and on the device my drawRect: method is being called 12 times, which is how many tiles are on the screen. In the simulator, the method gets called between 20 and 23 times, with all but the last few tiles being drawn twice.

爱情眠于流年 2024-11-05 05:33:16

这不是由于 setLevelsOfDetailBias 造成的吗?当我保留所有标准时,图块仅渲染一次(在设备上测试)。但是当我将 levelofdetailbias 设置为 2 时,图块会加载多次。我认为这是因为 CATiledLayer 在设备空闲时才开始缓存额外的细节级别。

Isn't this due to the setLevelsOfDetailBias ? When I leave everything standard the tiles only get rendered once (testing on the device). But when I set the levelofdetailbias to 2, the tiles get loaded multiple times. I think that's due to the fact that CATiledLayer just starts caching extra detail levels when the device is idle.

花间憩 2024-11-05 05:33:16

最终,答案并没有起作用。不过,让您的委托方法知道它是否已经绘制了该循环是相当简单的。

In the end, the answers didn't work. It is fairly simple, though, to make your delegate method be aware of whether or not it has drawn that cycle.

伪心 2024-11-05 05:33:15

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

我很久以前就已经向 Apple 报告了该错误(对于模拟器),最近又向 Apple 报告了该错误(对于 iPhone 4S)。苹果最近给人的印象是他们已经在 iOS 6 中解决了这个问题。

This is a bug in IOS. It happens when the CPU is dual-core, in that case there are two threads each requesting each tile. That means that the bug is present in the simulator, and on the iPhone 4S, but not on the other iPhone models. I assume it will also be present on dual-core iPads.

I have reported the bug to Apple long ago already (for the simulator) and recently again (for the iPhone 4S). Apple recently gave the impression that they have solved it in IOS 6.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文