一个辅助类,允许您异步地将视图绘制到带有缓存的UIImage,以获得出色的性能。
(这假设您对CoreGraphics以及某些事情(如混合)的工作原理有一些了解。如果没有,请阅读Twitter工程博客中的此篇博文:这篇博文)。
所以您在应用中有一个滚动速度慢的UITableView。您决定完全在CoreGraphics中实现cell绘制,在您的cell中实现-[UIView drawRect:]
。这是完美的,直到您必须绘制图像。与使用UIImageView
相比,CGContextDrawImage
非常慢。
因此,您会发现自己偏好使用UIImageView
,即使某些合成需要在cell中完成,因为由于它内部实现的疯狂优化,使用它绘制图像非常快。
但有时您确实需要使用CGContextDrawImage
,因为您必须执行更复杂的事情,比如蒙版、裁剪等。如果可以轻松地将结果传递给UIImageView
,从而从两个世界中获益,那会多么好?这就是MSCachedAsyncViewDrawing
所做的事情。
不言而喻,您不应把此方法应用到应用中所有的UIView上。这种方法有一个缺点,因为您正在增加更高的内存使用,以存储所有绘制操作的成果。 唯一知道使用MSCachedAsyncViewDrawing
是否可以提高特定情况下性能的方法是尝试它并进行比较。 作为一般规则,当-drawRect:
成为瓶颈,尤其是如果在其中使用CGContextDrawImage
时,使用它是合理的。这发生在您有多个复杂数据视图作为UITableView单元格时。
该示例项目包含两个视图控制器,它们都包含一个表格视图,表格的每一行都有三个实现了-drawInRect:
的视图。其中一个使用了MSCachedAsyncViewDrawing
,另一个则没有。这是一个如何使用此类及其性能优势的示例。将示例应用安装到您的iOS设备上并比较。由于屏幕上同时有很多视图,且它们都需要渲染一个UIImage
,这成为一个瓶颈。MSCachedAsyncViewDrawing
可以使这个过程异步,因此不会阻塞主线程,并获得完美的滚动性能,同时防止视图重复渲染。
这是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
,并将你可以传入-drawRect:
方法中的CGRect
传递给它。完成之后,它会用指定的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项目中使用,请在链接器标志中标记MSCachedAsyncViewDrawing.m
为-fobjc-arc
。版权所有(C)2012 MindSnacks
本软件依据Apache许可证版本2.0(“许可证”)分发;除非符合许可证要求或经书面同意,不得使用此文件。您可以在此处获得许可证副本:
http://www.apache.org/licenses/LICENSE-2.0
除非适用法律要求或书面同意,根据许可证分发的软件按照“原样”的基础分发,不提供任何性质的保证或条件,无论是明示的还是隐含的。有关许可证的具体语言,请参见许可证。