参考地址: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性能优化-预排版的更多相关文章

  1. 【腾讯Bugly干货分享】微信读书iOS性能优化

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/578c93ca9644bd524bfcabe8 “8小时内拼工作,8小时外拼成长 ...

  2. IOS 性能优化的建议和技巧

    IOS 性能优化的建议和技巧 本文来自iOS Tutorial Team 的 Marcelo Fabri,他是Movile的一名 iOS 程序员.这是他的个人网站:http://www.marcelo ...

  3. iOS性能优化:Instruments使用实战

    iOS性能优化:Instruments使用实战   最近采用Instruments 来分析整个应用程序的性能.发现很多有意思的点,以及性能优化和一些分析性能消耗的技巧,小结如下. Instrument ...

  4. iOS性能优化总结

    iOS性能优化总结.关于 iOS 性能优化梳理: 基本工具.业务优化.内存优化.卡顿优化.布局优化.电量优化. 安装包瘦身.启动优化.网络优化等. 关于iOS 性能优化梳理: 基本工具.业务优化.内存 ...

  5. iOS 性能优化收集

    iOS 性能调试 instrument Instrument Instrument之Core Animation工具 避免图层混合 ①.确保控件的opaque属性设置为true,确保backgroun ...

  6. 微信读书 iOS 性能优化总结

    微信读书作为一款阅读类的新产品,目前还处于快速迭代,不断尝试的过程中,性能问题也在业务的不断累积中逐渐体现出来.最近的 1.3.0 版本发布后,关于性能问题的用户反馈逐渐增多,为此,团队开始做一些针对 ...

  7. iOS 性能优化总结

    卡顿产生的原因 在 VSync信号到来后,系统图形服务会通过 CADisplayLink等机制通知 App,App主线程开始在 CPU中计算显示内容,比如视图的创建.布局计算.图片解码.文本绘制等.随 ...

  8. iOS性能优化-数组、字典便利时间复杂

    上图是几种时间复杂度的关系,性能优化一定程度上是为了降低程序执行效率减低时间复杂度. 如下是几种时间复杂度的实例: O(1) return array[index] == value; 复制代码 O( ...

  9. <转>iOS性能优化:Instruments使用实战

    最近采用Instruments 来分析整个应用程序的性能.发现很多有意思的点,以及性能优化和一些分析性能消耗的技巧,小结如下. Instruments使用技巧 关于Instruments官方有一个很有 ...

随机推荐

  1. yzoj P1948 取数字问题

    题意 sb题目,不多说,爆搜就能过. 代码 #include<bits/stdc++.h> using namespace std; int n,m,ans=1<<30,a[1 ...

  2. R:ggplot2数据可视化——基础知识

    1 安装 # 获取ggplot2 最容易的就是下载整个tidyverse: install.packages("tidyverse") # 也可以选择只下载ggplot2: ins ...

  3. HTML5 01. 布局、语义化标签、智能化表单、表单元素/标签/属性/事件、多媒体、类操作、自定义属性

    1.知识点 lang = “en”   所用语言是英文 文档结构更简洁 IE8一下不支持h5c3 书写更宽松 div没有语义 标签语义化:在合适的地方使用合适的标签 对seo优化友谊 网页经典布局 页 ...

  4. QRowTable表格控件(四)-效率优化之-优化数据源

    目录 一.开心一刻 二.问题分析 三.重写数据源 1.自己存储数据 2.重写data接口 四.比较 五.相关文章 原文链接:QRowTable表格控件(四)-效率优化之-优化数据源 一.开心一刻 一程 ...

  5. springmvc两种非注解的处理器映射器

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  6. BigDecimal转String

    代码: public static void main(String[] args) { // 浮点数的打印 System.out.println(new BigDecimal("10000 ...

  7. 单点登录(两种单点登录类型:SSO/CAS、相同一级域名的SSO)

    单点登录:SSO(Single Sign On) 什么是单点登录:大白话就是多个网站共享一个用户名和密码的技术,对于普通用户来说,只需要登录其中任意一个网站,登录其他网站的时候就能够自动登陆,不需要再 ...

  8. [币严区块链]以太坊(ETH)Dapp开发入门教程之宠物商店领养游戏

    阅读本文前,你应该对以太坊.智能合约有所了解,如果你还不了解,建议你先看以太坊是什么 除此之外,你最好还了解一些HTML及JavaScript知识. 本文通过实例教大家来开发去中心化应用,应用效果如图 ...

  9. java生成随机验证码图片

    import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; i ...

  10. 跟我学SpringCloud | 第十八篇:微服务 Docker 化之基础环境

    1. 容器化 Docker 的横空出世,给了容器技术带来了质的飞跃,Docker 标准化了服务的基础设施,统一了应用的打包分发,部署以及操作系统相关类库等,解决了测试生产部署时环境差异的问题.对于运维 ...