我正在阅读 Larry Osterman 的最新博客文章,内容是“调试 Windows Vista/7 音量控制中的闪烁问题”,我突然意识到我不记得曾经在我的 OS X 笔记本电脑上看到过应用程序闪烁。根据我的经验,即使是看起来写得不好的应用程序也可以避免闪烁问题。如果没有这变成 Apple 与 Windows 的争论(请),为什么 OS X 应用程序似乎没有同样的闪烁问题? 我很难相信 Apple 开发人员在编写无闪烁 GUI 方面非常出色,而 Windows 程序员则很糟糕,那么原因是什么? OS X API 是否要求所有 GUI 实现双缓冲?虽然某些应用程序的双缓冲调整大小行为稍显缓慢,但许多应用程序没有,而且它们仍然可以避免闪烁。 OS X 重画流程是否与 Windows 有根本不同,完全避免了
WM_ERASEBKGRND
问题?还是还有其他我没有看到的可能性?
当某些内容发生变化时,您(几乎总是)不会显式绘制到 Cocoa 中的窗口,从而使窗口的某个区域无效。框架稍后将降低视图的层次结构,并将窗口的脏区域绘制到辅助缓冲区中。然后它交换缓冲区。
您可以选择做出一些承诺,允许框架在重绘时采取快捷方式,但它们都是选择加入的。只有精明的观点才会受到影响。
如果你的 NSView 子类实现了
isOpaque
方法来返回 YES,那么框架将永远不会清除视图后面的任何内容或在其下绘制任何视图。
实现
preservesContentDuringLiveResize
返回 YES 会给您带来一些额外的责任,但可以提高窗口大小调整期间的性能。
10.6 添加了另外两个此类新 API,
layerContentsRedrawPolicy
和
layerContentsPlacement
。最后,自定义绘图不像 Windows 上那么常见。您看到的大多数视图都是框架提供的,而不是子类化的。框架提供意味着由苹果优化。
OSX 自首次发布以来就拥有合成引擎。当时,很多人认为这是一种疯狂的方法,因为当时发货的所有视频卡都经过优化以绘制位图(即窗口按钮和边框)而不是合成图像。在 OSX 的更高版本中,合成被推迟到 GPU(在 Quartz Extreme 中),因此大大减轻了 CPU 的负载,并使更多效果成为可能。
因为 Windows 合成器仅在 Windows Vista 中添加,并且仅当有可用的 GPU 并且您拥有正确版本的操作系统时,它不像 OSX 中的 Quartz 合成器那样普遍。由于合成器并不总是在 Windows 中使用,因此当某个区域被消隐并且负责绘制的应用程序无法足够快地重绘该区域时,就会发生闪烁。