iOS开发笔记之TableView优化
TableView相信只要是做iOS开发的就不会陌生,目前大多数iOS的app都是采用TabBar+NavigationBar+TableViewController这一主流框架,
既然用的这么频繁,肯定就会在开发过程中碰到一些问题--比如屏幕掉帧、卡顿等现象。这些现象大幅度的降低了用户的性能体验,并提高了crash的频率。
因此如何能优化好tableView就非常考验程序猿们的功底了。
本猿~啊呸,只要开发公司项目的时候就会遇到这类问题,当快速滑动tableView并且cell中有大量图片和其他控件需要加载时,就会出现严重掉帧(一般公司的项目当时大量采用xib现在逐渐用手写代码代替),有时还会crash。由于当时项目比较赶进度,所以没有时间去优化性能,这种情况直到功能基本完善为止,花了大量功夫进行性能优化。
接下来我会根据tableView的delegate以及dataSource方法的执行顺序进行一步一步的讲解。
首先当一个tableView需要显示内容的时候,首先会发送网络请求,向服务器请求数据,然后将数据转为我们可以使用的model后进行reload操作,接下来会向delegate和
dataSource请求数据。这时候会先调用- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 这个方法(假设section为1)。根据
model获取cell的行数然后调用-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath,根据model计算出cell的高度。由于
tableView是继承自scrollView,所以tableView也会有contentSize属性。它的contentSize取决于所有cell的高度和。和scrollView有一点不同,tableView只会管理可视的cell高度,这样做的目的是避免不必要的性能开销。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
这个代理方法的实现,在可见的页面是会重复绘制页面的,所以绝大部分人都会在这里做一些代码处理
比如:
static NSString *CellIdentifier = @"LazyTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
很常规的,防止cell对象无限的被创建,等同于android里面适配器的方法
以上举例代码是可以让cell被重复使用,一般大概只会在可见页面部分的几个cell会被创建下,其他的全部重复使用前面已经有的cell对象,到时候只要填充数据就可以了
那么仅仅只是如此,恐怕现在的cell自定义的页面不只是文本那么简单,多多少少都会带有一些图片吧,当你下滑时候是否发现有那么一点点的卡顿现成,特别是网络不好,而且还是在iPhone4上跑的就会更明显了
那么在cell里面异步加载图片是个程序员都会想到,但是如果你给每个循环对象都加上异步加载,并且下滑的时候,这一操作将会被执行,虽然是异步,但是一个app里面的线程过多也会卡顿的,特别是在下滑操作的时候给每个图片进行异步加载。
那么这里可以利用UIScrollViewDelegate代理很好的解决这问题:
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
可以识别tableview禁止或者减速滑动结束的时候进行异步加载图片。
以下方法来执行异步加载操作:
//获取可见部分的对象
NSArray *visiblePaths = [self.tableView indexPathsForVisibleRows];
for (NSIndexPath *indexPath in visiblePaths)
{
//获取的dataSource里面的对象,并且判断加载完成的不需要再次异步加载
<code>
}
同时在cell绘制中也做限制
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
if (self.tableView.dragging == NO && self.tableView.decelerating == NO)
{
//开始异步加载图片
<code>
}
tableview 停止滑动的时候开始异步加载图片
最后也别忘记在内存紧张的情况下释放调所有的异步线程,以保证的你的app不会被系统强制关闭
- (void)didReceiveMemoryWarning{
// 释放调异步加载图片的线程以及所有图片资源对象
<code>
}
还有千万别忘记销毁的时候手动把所有的使用到的代理设置nil。
还有一个利用线程和Runloop延迟加载图片的新思路:
[self.avatarImageView performSelector:@selector(serImage:)
withObjetc:downloadedImage
afterDelay:
inModes:@[NSDefaultRunLoopMode]]
+ (NSThread *)networkRequestThread {
static NSThread *_networkRequestThread = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_networkRequestThread =
[[NSThread alloc] initWithTarget:self
selector:@selector(networkRequestThreadEntryPoint:)
object:nil];
[_networkRequestThread start];
}); return _networkRequestThread;
iOS开发笔记之TableView优化的更多相关文章
- IOS开发笔记(4)数据离线缓存与读取
IOS开发笔记(4)数据离线缓存与读取 分类: IOS学习2012-12-06 16:30 7082人阅读 评论(0) 收藏 举报 iosiOSIOS 方法一:一般将服务器第一次返回的数据保存在沙盒里 ...
- iOS开发笔记7:Text、UI交互细节、两个动画效果等
Text主要总结UILabel.UITextField.UITextView.UIMenuController以及UIWebView/WKWebView相关的一些问题. UI细节主要总结界面交互开发中 ...
- iOS开发笔记-两种单例模式的写法
iOS开发笔记-两种单例模式的写法 单例模式是开发中最常用的写法之一,iOS的单例模式有两种官方写法,如下: 不使用GCD #import "ServiceManager.h" ...
- iOS开发笔记--什么时候调用layoutSubviews
iOS开发笔记--什么时候调用layoutSubviews 分类: iOS2014-04-22 16:15 610人阅读 评论(0) 收藏 举报 今天在写程序时候遇见layoutSubviews触发时 ...
- IOS开发笔记 IOS如何访问通讯录
IOS开发笔记 IOS如何访问通讯录 其实我是反对这类的需求,你说你读我的隐私,我肯定不愿意的. 幸好ios6.0 以后给了个权限控制.当打开app的时候你可以选择拒绝. 实现方法: [plain] ...
- 【Swift】iOS开发笔记(二)
前言 这个系列主要是一些开发中遇到的坑记录分享,有助于初学者跨过这些坑,攒够 7 条发一篇. 声明 欢迎转载,但请保留文章原始出处:) 博客园:http://www.cnblogs.com 农民伯 ...
- 菜鸟手下的iOS开发笔记(swift)
在阳春4月的一天晨会上,有一个老板和蔼的对他的一个菜鸟手下说:“你既然会Android,那你能不能开发iOS?” 不是说好的要外包的吗?内心跌宕,但是表面淡定的菜鸟手下弱弱的回道:“可以试试”. 第二 ...
- iOS开发:UITableView的优化技巧-异步绘制Cell
最近在微博上看到一个很好的开源项目VVeboTableViewDemo,是关于如何优化UITableView的.加上正好最近也在优化项目中的类似朋友圈功能这块,思考了很多关于UITableView的优 ...
- 【IOS开发笔记02】学生管理系统
端到端的机会 虽然现在身处大公司,但是因为是内部创业团队,产品.native.前端.服务器端全部坐在一起开发,大家很容易做零距离交流,也因为最近内部有一个前端要转岗过来,于是手里的前端任务好像可以抛一 ...
随机推荐
- 有反斜杠时候,CakePHP往pgsql插入数据异常
原始数据:INSERT INTO “public”.”tables” (“table”, “columns”) VALUES (‘table1\’, ‘{“col1″:false,”col2″:tru ...
- php接收二进制数据流转换成图片
<?php /** * 图片类 * @author Haroldphp@163.com * @version 1.0 * PHP默认只识别application/x-www.form-urlen ...
- 开源搜索引擎Sphinx 中启动多个搜索进程的方法
http://blog.163.com/yang_jianli/blog/static/1619900062010316504471/ 要在同一机器上启动多个sphinx搜索进程searchd,必须为 ...
- 【转】mybatis 获取自增id
转自:http://www.cnblogs.com/rhythmK/p/4047142.html 1.环境: mybatis : 3.2.3 spring-mybatis: 1.2.1 mysql: ...
- Redis总录
设计 选择合适的数据对象来存储对象:String,List,Hash(Entity角色对象),Set,Zset(需要排序): 选择存储是全局的,还是局部的: 机制 批处理(pipeline) 事务(w ...
- 不用第三个变量,将a,b两个值互换,会出现什么样的异常?
1 相互加减 a = a + b; b = a - b; a = a - b; 但会出现异常 如果a+b超过a类型的范围,俗称溢出异常. 2 指针操作交换地址 3 异或操作 转自网络搜索的答案
- JAVA 反射特性
1. 反射(概念):程序在运行期可以改变程序结构和变量类型,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力. 2. 反射的特性: •在运行时判断任意一个对象所属的类 •在运行时构造 ...
- Python连接Redis连接配置
1. 测试连接: Python 2.7.8 (default, Oct 20 2014, 15:05:19) [GCC 4.9.1] on linux2 Type "help", ...
- 【GDOI 2011 DAY2 T3】零什么的最讨厌了 (快速求阶乘、中国剩余定理)
问题描述: 林记在做数学习题的时候,经常遇到这种情况:苦思冥想了很久终于把问题解出来,结果发现答案是0,久而久之林记在得到习题答案是0的时候就没有了做出一道难题的成就感.于是林记决定:以后出题,答案一 ...
- 使用HttpClient向服务器发送restful post请求
直接上代码: public class RestClient { public static void main(String[] args) { String url = "http:// ...