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.前端.服务器端全部坐在一起开发,大家很容易做零距离交流,也因为最近内部有一个前端要转岗过来,于是手里的前端任务好像可以抛一 ...
随机推荐
- 初识pngdrive
初识是第一次认识的意思,类似的词还有初见.初遇.初心.初愿.初恋.初吻……梦里相见如初识,很美好的感觉.同样,今天我们要认识的也是一个比较神奇美妙的东西,至少对于程序员来说. 我曾经尝试过很多文件加密 ...
- JSON知多少-JSON数据结构
最近在开发微信平台,要使用JSON进行数据交换,之前用过JSON,但仅限于…… 在开发微信平台中,要使用JSON形式如下:代码片断1: { "button":[ { "t ...
- 学一点 mysql 双机异地热备份----快速理解mysql主从,主主备份原理及实践
双机热备的概念简单说一下,就是要保持两个数据库的状态 自动同步.对任何一个数据库的操作都自动应用到另外一个数据库,始终保持两个数据库数据一致. 这样做的好处多. 1. 可以做灾备,其中一个坏了可以切换 ...
- 【python】aassert 断言
语法 : assert 3>4 结果Traceback (most recent call last): File "<pyshell#0>", line 1, ...
- C语言-03流程控制
1.选择结构 char c = '+'; ; ; // 如果要在case后面定义新的变量,必须用大括号{}包住 注意变量的作用域的紊乱 if语句不加括号时,也要注意此问题 switch (c) { c ...
- Cocoapod错误 - Xcode6.4
当我从Xcode 6.3切换到Xcode6.4的时候,因为我是mac上安装了两个不同的版本,现在把Xcode 6.3卸掉了. 现在再次运行pod install命令的时候,提示如下错误: Upda ...
- python类的继承
继承一个类 如果已经定义了Person类,需要定义新的Student和Teacher类时,可以直接从Person类继承: class Person(object): def __init__(self ...
- ANDROID_MARS学习笔记_S04_003_用HttpClent发http请求
一.代码 1.xml(1)activity_main.xml <TextView android:layout_width="wrap_content" android:la ...
- Knockout绑定audio的pause事件导致音频无法停止
...时间过得真快, 一晃4天已经过去了, 然而自己并没有动笔写什么. 自省. 看了看今天的工作, 感觉好像没什么可写的. 不禁在想是不是一天一篇有点儿难. 再一想, 这分明就是在给自己找理由. 就是 ...
- logstash 贪婪匹配
05:50:47 192.168.5.116 GET /Hotel/HotelDisplay/cncqcqb230 - 80 - 192.168.9.2 Mozilla/5.0+(Macintosh; ...