文档章节

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

小春0618
 小春0618
发布于 2016/05/07 17:29
字数 1172
阅读 170
收藏 0

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

CPU资源消耗

1、对象创建

通过 Storyboard 创建视图对象时,其资源消耗会比直接通过代码创建对象要大非常多

2、对象创建

UIView 的关于显示相关的属性(比如 frame/bounds/transform)等实际上都是 CALayer 属性映射来的,所以对 UIView 的这些属性进行调整时,消耗的资源要远大于一般的属性

当视图层次调整时,UIView、CALayer 之间会出现很多方法调用与通知,所以在优化性能时,应该尽量避免调整视图层次、添加和移除视图

3、对象销毁

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

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

4、布局计算

其最终都会落到对 UIView.frame/bounds/center 等属性的调整上。上面也说过,对这些属性的调整非常消耗资源,所以尽量提前计算好布局,在需要时一次性调整好对应属性,而不要多次、频繁的计算和调整这些属性。

5、文本计算

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

如果你用 CoreText 绘制文本,那就可以先生成 CoreText 排版对象,然后自己计算了,并且 CoreText 对象还能保留以供稍后绘制使用。

6、文本渲染

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

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

7、图片解码

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

8、图片绘制

图像的绘制通常是指用那些以 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 上去。

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



© 著作权归作者所有

小春0618
粉丝 8
博文 40
码字总数 10552
作品 0
海淀
程序员
私信 提问
加载中

评论(0)

iOS高仿微信悬浮窗、忍者小猪游戏、音乐播放器、支付宝、今日头条布局滚动效果等源码

iOS精选源码 iOS WKWebView的使用源码(http://www.code4app.com/thread-30279-1-1.html) 模仿apple music 小播放器的交互实现(http://www.code4app.com/thread-30282-1-1.html) 高仿微信的悬......

sunnyaigd
2018/06/26
153
0
iOS动画效果合集、飞吧企鹅游戏、换肤方案、画板、文字效果等源码

iOS精选源码 动画知识运用及常见动画效果收集(http://www.code4app.com/thread-13354-1-1.html) 3D卡片拖拽卡片叠加卡片(http://www.code4app.com/thread-30475-1-1.html) iFIERO - FLYING P......

sunnyaigd
2018/07/18
26
0
fir.im Weekly - iOS 保持界面流畅的技巧

生命不息,coding 不止。本期 fir.im Weekly 收集了微博上的热转资源,包含 Android、iOS 开发工具、源码分享,产品 UI 设计的好文章,还有一些程序员成长的 Tips,希望看完你会有所收获。 ...

风起云飞fir_im
2015/11/16
144
0
iOS涂色涂鸦效果、Swift仿喜马拉雅FM、抽屉转场动画、拖拽头像、标签选择器等源码

iOS精选源码 LeeTagView 标签选择控件(http://www.code4app.com/thread-31033-1-1.html) 为您的用户显示界面添加美观的加载视图(http://www.code4app.com/thread-31038-1-1.html) Swift4: 可......

sunnyaigd
2018/09/19
68
0
iOS播放器、Flutter高仿书旗小说、卡片动画、二维码扫码、菜单弹窗效果等源码

iOS精选源码 全网最详细购物车强势来袭(http://www.code4app.com/thread-10664-1-1.html) 一款优雅易用的微型菜单弹窗(类似QQ和微信右上角弹窗)(http://www.code4app.com/thread-12069-1-1....

Android爱开源
2019/01/23
561
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Boot 如何以 Web 应用的方式启动

在 Spring Boot 启动的时候,在进程完成后会自动退出。 如何让 Spring Boot 以 Web 方式启动,并且进程不退出呢? 需要确定下 Web 的这个依赖是否在你的依赖中。 <dependency> ...

honeymoose
27分钟前
36
0
leetcode892(三维形体的表面积)--C语言实现

求: 在 N * N 的网格上,我们放置一些 1 * 1 * 1 的立方体。 每个值 v = grid[i][j] 表示 v 个正方体叠放在对应单元格 (i, j) 上。 请你返回最终形体的表面积。 示例 1: 输入:[[2]] 输出:...

拓拔北海
32分钟前
48
0
使用* args和** kwargs [重复] - Use of *args and **kwargs [duplicate]

问题: This question already has answers here : 这个问题已经在这里有了答案 : What does ** (double star/asterisk) and * (star/asterisk) do for parameters? **(双星号/星号)和*(......

技术盛宴
37分钟前
46
0
spring-boot之@ConfigurationProperties的使用

@ConfigurationProperties是什么? Using the @Value("${property}") annotation to inject configuration properties can sometimes be cumbersome, especially if you are working with mu......

书中迷梦
38分钟前
67
0
让你快速掌握_正则表达式_的技巧(二)

经过上篇的快速入门了正则表达式,今天就带你快速掌握正则表达式的技巧, 话不多说,直接上干货! 正则表达式-附录【重点】 一. 规则 规则:. 含义:代表的是某一位,可以是任何字符 例如:匹配规...

煌sir
41分钟前
49
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部