使用 CGLayer 缓存 UITableView 中的单元格

发布于 2024-08-17 04:58:36 字数 1109 浏览 4 评论 0原文

我正在尝试提高应用程序中的滚动性能。我遵循了所有普遍接受的建议(用 CG 自己绘制、单元格不透明、没有子视图等),但当我们有后台 CPU 和网络活动时,有时它仍然会卡顿。

这里提出了一种解决方案:

http:// www.fieryrobot.com/blog/2008/10/08/more-glassy-scrolling-with-uitableview/

是缓存单元格的位图快照,我们尝试过。但位图很模糊并且占用了大量内存(每个位图大约几百 kb)。

该链接的评论中的一项建议是使用 CGLayer 或 CALayer(?) 缓存单元格,因为它们会进入显卡的内存。有几个问题,

1)有人尝试过吗?示例代码?

2)iphone/ipod touch显卡有多少内存?这有什么意义吗?

3)还有其他加快速度的建议吗?


更多信息

我使用了 CPU 采样器(在电话上)并系统地从单元中消除了一些东西来找出问题。有几件事:

1)这不是单元格的设置。如果我仅删除绘图调用(drawinrect 等),但保留设置,则它是玻璃状的。

2)这不是最小图像(25x25 png)的绘制,如果我把它放进去就可以了。

3)如果我添加第二个或第三个图像(第一个是大背景320x1004kB,另一个是按钮图像61x35 4kB),它就会卡顿。我在类方法中获取两个 UIImage,因此它被缓存。

4)文本也是一个问题。看起来 by drawRect 花费了 75% 的时间在我正在使用的三个 NSString drawInRect 方法中。像:

[mytext drawInRect:drawrect withFont:myFont lineBreakMode:UILineBreakModeTailTruncation];

这些调用似乎通过网络核心,也许这会导致一些口吃?我需要能够格式化两行文本和一小段文本。我需要能够用省略号截断文本。我可以在关键路径之外执行这些操作并缓存它们吗?我可以用一层来做这部分吗?

I am trying to improve the performance of scrolling in our app. I have followed all of the generally accepted advice (draw it yourself with CG, the cell is opaque, no subviews, etc.) but it still stutters sometimes when we have background CPU and network activity.

One solution stated here:

http://www.fieryrobot.com/blog/2008/10/08/more-glassy-scrolling-with-uitableview/

is to cache bitmap snapshots of the cells, which we tried. But the bitmaps were fuzzy and took up a ton of memory (~a few hundred kb each).

One suggestion in the comments of that link is to cache the cells using CGLayer or CALayer(?) because they go to the graphic card's memory. So a few questions,

1) Has any tried this? Sample code?

2) How much memory does the iphone/ipod touch graphics card have? Does this make any sense?

3) Any other suggestions for speeding things up?


More information

I used the CPU sampler (on the phone) and systematically eliminated things from the cell to figure out the problem. A few things:

1) It isn't the setup of the cell. If I remove just the drawing calls (drawinrect etc), but leave the setup, it is glassy.

2) It isn't the drawing of the smallest image (25x25 png), if I put that in it is fine.

3) If I add the second or third image (the first is a big background 320x1004kB, the other is a button image 61x35 4kB) it stutters. I am grabbing both UIImages in a class method, so it is cached.

4) The text is also a problem. It looks like by drawRect spends 75% of its time in the three NSString drawInRect methods I am using. Like:

[mytext drawInRect:drawrect withFont:myFont lineBreakMode:UILineBreakModeTailTruncation];

Those calls seem to go through webcore, perhaps that causes some of the stutters? I need to be able to format two lines of text, and one small paragraph of text. I need the ability to truncate the text with ellipses. Can I perform these out of the critical path and cache them? May I can do that part with a layer?

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

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

发布评论

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

评论(2

故人如初 2024-08-24 04:58:36

CGLayers 不缓存在 GPU 上,它们在将 Core Graphics 元素绘制到上下文的过程中使用。 CALayers 确实将其视觉内容缓存在 GPU 上。这可以“隐藏”您的一些内存使用情况,但如果您保留大量 CALayers,您仍然会遇到内存问题。

老实说,如果您遵循 Loren Brichter 等人所描述的表格视图最佳实践,通过 Core Graphics 在一层中绘制所有内容,使单元格不透明,并遵守表格视图的单元格重用机制,您无能为力。无论您如何优化,iPhone 上的 CPU 超载都会导致滚动卡顿。惯性滚动动画确实需要一些 CPU 能力才能运行。

最后要确保的一件事是您引用的后台 CPU 和网络进程确实在后台线程上运行。主线程中运行的任何内容都会导致您的交互方法在该任务处理时暂停,可能会增加滚动的不稳定性。

CGLayers are not cached on the GPU, they are used during the process of drawing Core Graphics elements to a context. CALayers do have their visual contents cached on the GPU. This can "hide" some of your memory usage, but you're still going to run into memory problems if you hold on to a lot of CALayers.

Honestly, if you've followed the table view best practices, as described by Loren Brichter and others, of drawing all of your content via Core Graphics in one layer, making your cell opaque, and obeying the cell reuse mechanism of the table view, there isn't much more you can do. Overloading the CPU on the iPhone will cause stuttering of your scrolling, no matter how optimized you can make it. The inertial scrolling animation does require some CPU power to run.

One last thing to make sure of is that the background CPU and network processes you refer to really are running on a background thread. Anything running in the main thread will cause your interaction methods to pause while that task is processing, potentially adding to the choppiness of your scrolling.

把时间冻结 2024-08-24 04:58:36

在深入优化之前,您是否使用单元重用机制 ([tableView dequeueReusableCellWithIdentifier:]) 在委托的 tableView:cellForRowAtIndexPath 中创建 UITableViewCell : ?

另外,您是否使用 Instruments 的活动监视器在模拟器中运行代码?将间隔设置为 1 毫秒(我发现默认值 - 10 毫秒 - 太大了)并查看滚动时大部分时间都花在哪里。

Before you go too deep into the optimisation, are you using the cell reuse mechanism ([tableView dequeueReusableCellWithIdentifier:]) for creating UITableViewCells in your delegate's tableView:cellForRowAtIndexPath: ?

Also, have you run the code in the Simulator using Instruments' Activity Monitor? Set the interval to 1 ms (I found the default - 10 ms - too big for this) and see where most of your time is spent when doing the scrolling.

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