我假设您的服务器发送部分更新,并且不会在每次更新时发送全屏快照。
简单的技术就是创建一个CGBitmapContext并保留它。当您获得新像素时,直接更新其数据(使用CGContextFillRect会慢得多),然后使用它创建图像CGBitmapContextCreateImage并将该图像分配给view.layer.contents. (不要忘记将图像存储在该属性后释放它!)
但正如您所发现的,您每次都必须创建一个新图像。为什么?ACGImage是不可变的。为了强制不变性,Core Graphics 在创建CGImage. 然后,当您在图层中显示图像时,iOS 必须再次将像素数据复制到窗口服务器(这是一个单独的过程)。复制整个屏幕的像素数据很慢:您要复制的数据大小从 614 KB(iPhone 3GS 及更早版本)到 12.6 MB(Retina iPad)不等,具体取决于设备。
在仍停留在 UIKit 和 Core Animation 的世界中的情况下,可以加速这一过程的一种方法是使用图层网格平铺屏幕。假设您使用每个 64x64 像素的图层对其进行平铺。CGBitmapContext您为每个层创建一个。然后,当您从服务器接收像素数据时,您会更新相应的数据CGBitmapContext,然后仅更新需要它的图层的内容。当屏幕的一小部分发生变化时,您将仅更新一个或几个图块,因此您复制的数据会少得多。在 64x64 像素下,每个图块复制 16 KiB。您可能需要尝试几种不同的尺寸,以确定哪种尺寸最有效。
如果这仍然不够快,您将需要离开 UIKit 和 Core Animation 的世界并使用 OpenGL ES。在 iOS 上,OpenGL ES 提供对视频卡的最直接访问,除非您的电子邮件地址以@apple.com. 您可以使用像素数据创建纹理,并使用该纹理绘制两个三角形(排列成矩形),覆盖CAEAGLLayer. 当您获得新的像素数据时,您可以使用将其写入纹理glTexSubImage2D并重新绘制三角形。如果您没有做过太多 OpenGL 编程,这将是一项相当大的工作。