iOS保持界面流畅技巧文章阅读摘录

下列内容为阅读文章的摘录,原文连接:http://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/ios

CPU资源消耗缓存

一、对象建立安全

经过 Storyboard 建立视图对象时,其资源消耗会比直接经过代码建立对象要大很是多网络

二、对象建立异步

UIView 的关于显示相关的属性(好比 frame/bounds/transform)等实际上都是 CALayer 属性映射来的,因此对 UIView 的这些属性进行调整时,消耗的资源要远大于通常的属性async

当视图层次调整时,UIView、CALayer 之间会出现不少方法调用与通知,因此在优化性能时,应该尽可能避免调整视图层次、添加和移除视图布局

三、对象销毁性能

这里有个小 Tip:把对象捕获到 block 中,而后扔到后台队列去随便发送个消息以免编译器警告,就可让对象在后台线程销毁了。优化

NSArray *tmp = self.array;
self.array = nil;
dispatch_async(queue, ^{
   [tmp class];
});

四、布局计算spa

其最终都会落到对 UIView.frame/bounds/center 等属性的调整上。上面也说过,对这些属性的调整很是消耗资源,因此尽可能提早计算好布局,在须要时一次性调整好对应属性,而不要屡次、频繁的计算和调整这些属性。

五、文本计算

若是你对文本显示没有特殊要求,能够参考下 UILabel 内部的实现方式:用 [NSAttributedString boundingRectWithSize:options:context:] 来计算文本宽高,用 -[NSAttributedString drawWithRect:options:context:] 来绘制文本。尽管这两个方法性能不错,但仍旧须要放到后台线程进行以免阻塞主线程。

若是你用 CoreText 绘制文本,那就能够先生成 CoreText 排版对象,而后本身计算了,而且 CoreText 对象还能保留以供稍后绘制使用。

六、文本渲染

屏幕上能看到的全部文本内容控件,包括 UIWebView,在底层都是经过 CoreText 排版、绘制为 Bitmap 显示的。

CoreText 对象建立好后,能直接获取文本的宽高等信息,避免了屡次计算(调整 UILabel 大小时算一遍、UILabel 绘制时内部再算一遍);CoreText 对象占用内存较少,能够缓存下来以备稍后屡次渲染

七、图片解码

当你用 UIImage 或 CGImageSource 的那几个方法建立图片时,图片数据并不会马上解码。图片设置到 UIImageView 或者 CALayer.contents 中去,而且 CALayer 被提交到 GPU 前,CGImage 中的数据才会获得解码。这一步是发生在主线程的,而且不可避免。若是想要绕开这个机制,常见的作法是在后台线程先把图片绘制到 CGBitmapContext 中,而后从 Bitmap 直接建立图片。目前常见的网络图片库都自带这个功能。

八、图片绘制

图像的绘制一般是指用那些以 CG 开头的方法把图像绘制到画布中,而后从画布建立图片并显示这样一个过程。这个最多见的地方就是 [UIView drawRect:] 里面了。因为 CoreGraphic 方法一般都是线程安全的,因此图像的绘制能够很容易的放到后台线程进行。一个简单异步绘制的过程大体以下(实际状况会比这个复杂得多,但原理基本一致):

- (void)display {
   dispatch_async(backgroundQueue, ^{
       CGContextRef ctx = CGBitmapContextCreate(...);
       // draw in context...
       CGImageRef img = CGBitmapContextCreateImage(ctx);
       CFRelease(ctx);
       dispatch_async(mainQueue, ^{
           layer.contents = img;
       });
   });
}

为了减轻这种状况的 GPU 消耗,应用应当尽可能减小视图数量和层次,并在不透明的视图里标明 opaque 属性以免无用的 Alpha 通道合成。

CALayer 的 border、圆角、阴影、遮罩(mask),CASharpLayer 的矢量图形显示,一般会触发离屏渲染(offscreen rendering),而离屏渲染一般发生在 GPU 中。当一个列表视图中出现大量圆角的 CALayer,而且快速滑动时,能够观察到 GPU 资源已经占满,而 CPU 资源消耗不多。

这时界面仍然能正常滑动,但平均帧数会降到很低。为了不这种状况,能够启用CALayer的shouldRasterize 属性但这会把本来离屏渲染的操做转移到 CPU 上去。

对于只须要圆角的某些场合,也能够用一张已经绘制好的圆角图片覆盖到本来视图上面来模拟相同的视觉效果。最完全的解决办法,就是把须要显示的图形在后台线程绘制为图片,避免使用圆角、阴影、遮罩等属性。

相关文章
相关标签/搜索