iOS性能优化-预排版
参考地址:https://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/
前面一篇说了异步绘制文字,异步渲染图片,这篇主要是预排版,经过这三种处理之后,基本上已经非常流畅了.
下面的demo就使用了这三种处理来做优化.
我使用的demo是我之前做的一个列表:https://www.cnblogs.com/alan12138/p/9619336.html
下面是优化前的demo地址和效果:
github:https://github.com/alan12138/InfoFlow

可以看到滑动很快的时候到最后已经达到33FPS的程度了,当然如果正常浏览不那么快的时候还是没有很大差别的.
下面是优化后的demo地址和效果:
github:https://github.com/alan12138/Interview-question/tree/master/3/InfoFlow

可以看到无论如何滑动,基本稳定在60FPS.
因为图片异步渲染和异步绘制文字我上一篇博文已经写过了所以这篇主要写一下预排版.
预排版主要做的就是这件事:
dispatch_async(dispatch_get_global_queue(, ), ^{
//造一些数据
self.feeds = [NSMutableArray array];
for (int i = ; i < ; i++) {
APMyFeed *myFeed = [[APMyFeed alloc] init];
myFeed.headIcon = @"https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2118739199,3378602431&fm=26&gp=0.jpg";
myFeed.name = @"王者小能手";
myFeed.sex = @"性别女";
...
}
myFeed.time = @"5分钟前";
myFeed.location = @"南京·麒麟国际企业研发园";
myFeed.comment = @"";
myFeed.zan = @"";
myFeed.expand = NO;
[self.feeds addObject:myFeed];
}
self.layouts = [NSMutableArray array];
for (APMyFeed *feed in self.feeds) {
APMyFeedLayout *layout = [[APMyFeedLayout alloc] init];
layout.feed = feed;
[self.layouts addObject:layout];
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.mainTableView reloadData];
});
});
获取数据之后,异步将所有控件排版通过已获取的数据提前计算出来,并保存在一个数组中,处理完之后再返回主线程刷新列表加载数据.
数组中的每个元素都是APMyFeedLayout类型,其中保存了每一条的数据和通过数据计算出来的排版数据.如此所有控件的排版和行高计算都已经在列表加载之前完成了,避免了滑动过程中的大部分计算,所以在滑动过程中只剩下了一件事,就是把计算好的数据赋值而已.
#pragma mark - UITableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.layouts.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
APMyFeedTableViewCell *cell = [APMyFeedTableViewCell cellWithTableView:tableView]; APMyFeedLayout *layout = self.layouts[indexPath.row];
cell.layout = layout;
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
APMyFeedLayout *layout = self.layouts[indexPath.row];
return layout.height;
}
排版的计算在APMyFeedLayout中进行,主要就是在setFeed的时候通过feed数据计算出每个控件的frame,并保存在每个APMyFeedLayout对象中,用于后面使用.
@implementation APMyFeedLayout
- (void)setFeed:(APMyFeed *)feed {
_feed = feed;
CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
self.iconRect = CGRectMake(, , , );
CGFloat nameW = [CommonUtils calcWidthWithTitle:feed.name font:nameFont];
CGFloat nameH = [CommonUtils calcLabelHeight:feed.name fontSize:nameFont width:nameW];
self.nameRect = CGRectMake(CGRectGetMaxX(self.iconRect) + , , nameW, nameH);
self.sexRect = CGRectMake(CGRectGetMaxX(self.iconRect) + , CGRectGetMaxY(self.nameRect) + , , );
...
self.seperatorViewRect = CGRectMake(, CGRectGetMaxY(self.delRect) + , screenW, );
self.height = CGRectGetMaxY(self.seperatorViewRect);
}
@end
最后就是在cell中赋值了:
- (void)setLayout:(APMyFeedLayout *)layout {
_layout = layout;
[self.headIconBtn sd_setImageWithURL:[NSURL URLWithString:layout.feed.headIcon] forState:UIControlStateNormal];
self.headIconBtn.frame = layout.iconRect;
[self.headIconBtn addRadius:self.headIconBtn.bounds.size.width / corners:UIRectCornerAllCorners bgColor:[UIColor whiteColor]];
self.nameLabel.text = layout.feed.name;
self.nameLabel.frame = layout.nameRect;
[self.sexIconView setImage:[UIImage imageNamed:layout.feed.sex]];
self.sexIconView.frame = layout.sexRect;
self.contentLabel.text = layout.feed.content;
self.contentLabel.frame = layout.contentRect;
self.timeLabel.text = layout.feed.time;
self.timeLabel.frame = layout.timeRect;
self.locationLabel.text = layout.feed.location;
self.locationLabel.frame = layout.locationRect;
self.delBtn.frame = layout.delRect;
self.zanLabel.text = layout.feed.zan;
self.zanLabel.frame = layout.zanLabelRect;
self.commentLabel.text = layout.feed.comment;
self.commentLabel.frame = layout.commentLabelRect;
...
}
iOS性能优化-预排版的更多相关文章
- 【腾讯Bugly干货分享】微信读书iOS性能优化
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/578c93ca9644bd524bfcabe8 “8小时内拼工作,8小时外拼成长 ...
- IOS 性能优化的建议和技巧
IOS 性能优化的建议和技巧 本文来自iOS Tutorial Team 的 Marcelo Fabri,他是Movile的一名 iOS 程序员.这是他的个人网站:http://www.marcelo ...
- iOS性能优化:Instruments使用实战
iOS性能优化:Instruments使用实战 最近采用Instruments 来分析整个应用程序的性能.发现很多有意思的点,以及性能优化和一些分析性能消耗的技巧,小结如下. Instrument ...
- iOS性能优化总结
iOS性能优化总结.关于 iOS 性能优化梳理: 基本工具.业务优化.内存优化.卡顿优化.布局优化.电量优化. 安装包瘦身.启动优化.网络优化等. 关于iOS 性能优化梳理: 基本工具.业务优化.内存 ...
- iOS 性能优化收集
iOS 性能调试 instrument Instrument Instrument之Core Animation工具 避免图层混合 ①.确保控件的opaque属性设置为true,确保backgroun ...
- 微信读书 iOS 性能优化总结
微信读书作为一款阅读类的新产品,目前还处于快速迭代,不断尝试的过程中,性能问题也在业务的不断累积中逐渐体现出来.最近的 1.3.0 版本发布后,关于性能问题的用户反馈逐渐增多,为此,团队开始做一些针对 ...
- iOS 性能优化总结
卡顿产生的原因 在 VSync信号到来后,系统图形服务会通过 CADisplayLink等机制通知 App,App主线程开始在 CPU中计算显示内容,比如视图的创建.布局计算.图片解码.文本绘制等.随 ...
- iOS性能优化-数组、字典便利时间复杂
上图是几种时间复杂度的关系,性能优化一定程度上是为了降低程序执行效率减低时间复杂度. 如下是几种时间复杂度的实例: O(1) return array[index] == value; 复制代码 O( ...
- <转>iOS性能优化:Instruments使用实战
最近采用Instruments 来分析整个应用程序的性能.发现很多有意思的点,以及性能优化和一些分析性能消耗的技巧,小结如下. Instruments使用技巧 关于Instruments官方有一个很有 ...
随机推荐
- XML序列化CDATA
不可避免的遇到对接需要使用XML文档的第三方系统,某些节点内容特殊,序列化时需特殊处理,解决方案是实现IXmlSerializable接口. /// <summary> /// Perso ...
- Three.js 开发机房(四)
这一节我们讲讲怎么画机柜,其实机柜如果作的复杂一点.逼真一点可以用3D建模工具,不过一般的项目中也不用做的那么麻烦,那我们就可以将机柜抽象以下,首先它是一块具有长宽高的立方体铁块,然后我们从中间在掏掉 ...
- Fiddler 手机爬虫
Fiddler抓包工具 配置Fiddler 添加证书信任,Tools - Options - HTTPS,勾选 Decrypt Https Traffic 后弹出窗口,一路确认 ...from bro ...
- VScode神器如何同步配置和所装插件
由于近期编辑器换用vscode,回到家里也需要写代码,但是家里电脑也需要安装vscode,并设置相同配置和插件.想到以前webstrom可以直接导出配置然后安装. 但是vscode无此配置,突发奇想g ...
- lambda表达式与匿名内部类与双冒号(::)
lambda表达式在只有一条代码时还可以引用其他方法或构造器并自动调用,可以省略参数传递,代码更加简洁,引用方法的语法需要使用::符号.lambda表达式提供了四种引用方法和构造器的方式: 引用对象的 ...
- spring中的XML Catalog配置
XML Catalog配置: 1.window-->preferences-->XML Catalog 2.如图: 点击File System,选择下图中的最后一个 图二中的key时sch ...
- SpringCloud入门[转]
原文链接 一. 网站的架构演变 网络架构由最开始的三层mvc渐渐演变.传统的三层架构后来在互联网公司让几百人几千人同时开发一个项目已经变得不可行,并且会产生代码冲突的问题.基于SOA面向服务开 ...
- Spring Boot2 系列教程(五)Spring Boot中的 yaml 配置
搞 Spring Boot 的小伙伴都知道,Spring Boot 中的配置文件有两种格式,properties 或者 yaml,一般情况下,两者可以随意使用,选择自己顺手的就行了,那么这两者完全一样 ...
- get和post请求方式的区别
1.用途方面: get是向服务器请求数据,post是向服务器发送数据. 2.大小方面: get发送数据上有大小限制,post理想上无大小限制,实际上有限制. 3.安全方面: get请求的数据会显示在地 ...
- 大数据平台搭建 - cdh5.11.1 - spark源码编译及集群搭建
一.spark简介 Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎,Spark 是一种与 hadoop 相似的开源集群计算环境,但是两者之间还存在一些不同之处,这些有用的不同 ...