一个辅助类,允许您异步地将视图绘制到 UIIMage 中,并具有缓存以实现出色的性能。
(这假设您对 CoreGraphics 以及一些像混合等东西有所了解。如果没有,请阅读 Twitter 工程博客中的这篇文章)。
因此,您有一个在应用程序中的 UITableView,它滚动得很慢。您决定将 cell 绘制完全在 CoreGraphics 中实现,在您的 cell 中实现 -[UIView drawRect:]
。这是完美的,直到您需要绘制图像。CGContextDrawImage
与使用 UIImageView
相比是 **非常慢**。
因此,您会发现自己在很多情况下更喜欢使用 UIImageView
即使在 cell 上需要进行一些合成,因为使用它渲染图像的 **速度非常快**,因为它实现了大量的内部优化。
但有时您确实需要使用 CGContextDrawImage
,因为您需要进行更复杂的操作,如蒙版、裁剪等。如果能这样做,同时轻松地将结果传递给 UIImageView
,将两个世界的优点结合起来,那不是很好吗?这正是 MSCachedAsyncViewDrawing
所做的。
不用说,您不应该只是将其应用到应用程序中的所有 UIView 上。这种做法有一个缺点,因为它会因为存储所有绘制操作的结果而增加更高的内存使用量。知道使用 MSCachedAsyncViewDrawing
是否能够在您的特定情况下提高性能的唯一方法是尝试它,并进行比较。一般来说,当 -drawRect:
成为瓶颈时,特别是当它在内部使用 CGContextDrawImage
时,**使用它的意义**更大。这经常发生在您有多个复杂视图在 UITableView
的 cells 中时。
这个示例项目包含两个视图控制器,它们各自包含一个表格视图,每个行都有3个实现 -drawInRect:
的视图。其中一个使用 MSCachedAsyncViewDrawing
,另一个则没有。这是一个展示如何使用此类及其性能优势的例子。在您的iOS设备上安装示例应用并进行比较。这也是此类的一个典型用例,因为屏幕上同时有很多视图,它们都必须渲染一个 UIImage
类型,这会成为瓶颈。 MSCachedAsyncViewDrawing
使其异步执行,因此不会阻塞主线程,并获得完美的滚动性能,并且还防止视图重复渲染。
pod 'MSCachedAsyncViewDrawing', '~> 1.0.0'
来使用 cocoapods 进行安装。MSCachedAsyncViewDrawing.(h+m)
文件添加到您的项目中。这是 MSCachedAsyncViewDrawing
中的主要方法
- (void)drawViewAsyncWithCacheKey:(NSString *)cacheKey
size:(CGSize)imageSize
backgroundColor:(UIColor *)backgroundColor
drawBlock:(MSCachedAsyncViewDrawingDrawBlock)drawBlock
completionBlock:(MSCachedAsyncViewDrawingCompletionBlock)completionBlock;
块类型声明如下
typedef void (^MSCachedAsyncViewDrawingDrawBlock)(CGRect frame);
typedef void (^MSCachedAsyncViewDrawingCompletionBlock)(UIImage *drawnImage);
MSCachedAsyncViewDrawing
将在后台线程中获取 drawBlock
并调用它,同时传递一个 CGRect
,您可以将它传递给视图的 -drawRect:
方法。完成后,它会使用指定的 cacheKey
缓存包含 UIImage
对象,并使用它调用您的 completionBlock
。
后续的相同 cacheKey
调用将导致立即调用 completionBlock
,而无需调用 drawBlock,因为它将从缓存中获取渲染的图像。
缓存是使用 NSCache
实现的,因此您不必担心过度缓存图像,因为 iOS 会处理随着可用内存减少而移除对象。
如果您希望在渲染发生时阻塞UI,因为您想要确保图像视图在任何时候都不为空,可以使用这个其他方法,它立即返回 UIImage
对象
- (UIImage *)drawViewSyncWithCacheKey:(NSString *)cacheKey
size:(CGSize)imageSize
backgroundColor:(UIColor *)backgroundColor
drawBlock:(MSCachedAsyncViewDrawingDrawBlock)drawBlock;
MSCachedAsyncViewDrawing
兼容iOS5.0及以上版本。MSCachedAsyncViewDrawing
使用ARC。要在非ARC项目中使用,请使用链接器标志 -fobjc-arc
标记 MSCachedAsyncViewDrawing.m
。MSCachedAsyncViewDrawing
遵循MIT许可证。有关更多信息,请参阅LICENSE文件。