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优化的更多相关文章

  1. IOS开发笔记(4)数据离线缓存与读取

    IOS开发笔记(4)数据离线缓存与读取 分类: IOS学习2012-12-06 16:30 7082人阅读 评论(0) 收藏 举报 iosiOSIOS 方法一:一般将服务器第一次返回的数据保存在沙盒里 ...

  2. iOS开发笔记7:Text、UI交互细节、两个动画效果等

    Text主要总结UILabel.UITextField.UITextView.UIMenuController以及UIWebView/WKWebView相关的一些问题. UI细节主要总结界面交互开发中 ...

  3. iOS开发笔记-两种单例模式的写法

    iOS开发笔记-两种单例模式的写法   单例模式是开发中最常用的写法之一,iOS的单例模式有两种官方写法,如下: 不使用GCD #import "ServiceManager.h" ...

  4. iOS开发笔记--什么时候调用layoutSubviews

    iOS开发笔记--什么时候调用layoutSubviews 分类: iOS2014-04-22 16:15 610人阅读 评论(0) 收藏 举报 今天在写程序时候遇见layoutSubviews触发时 ...

  5. IOS开发笔记 IOS如何访问通讯录

    IOS开发笔记  IOS如何访问通讯录 其实我是反对这类的需求,你说你读我的隐私,我肯定不愿意的. 幸好ios6.0 以后给了个权限控制.当打开app的时候你可以选择拒绝. 实现方法: [plain] ...

  6. 【IOS开发笔记02】学生管理系统

    端到端的机会 虽然现在身处大公司,但是因为是内部创业团队,产品.native.前端.服务器端全部坐在一起开发,大家很容易做零距离交流,也因为最近内部有一个前端要转岗过来,于是手里的前端任务好像可以抛一 ...

  7. iOS开发笔记4:HTTP网络通信及网络编程

    这一篇主要总结iOS开发中进行HTTP通信及数据上传下载用到的方法.网络编程中常用的有第三方类库AFNetworking或者iOS7开始新推出的NSURLSession,还有NSURLSession的 ...

  8. iOS开发笔记--宏定义的黑魔法 - 宏菜鸟起飞手册

    宏定义在C系开发中可以说占有举足轻重的作用.底层框架自不必说,为了编译优化和方便,以及跨平台能力,宏被大量使用,可以说底层开发离开define将寸步难行.而在更高层级进行开发时,我们会将更多的重心放在 ...

  9. iOS开发笔记系列-基础1(数据类型与表达式)

    学习iOS开发快两年了,去年完成MagViewer之后就因为公司的其他业务繁重,除了维护这个应用之外,只是断断续续地自己做一些实验开发,没有再发布新的应用,这里想整理一下学习过程中的笔记,以便加深印象 ...

随机推荐

  1. setTimeout 的黑魔法

    setTimeout,前端工程师必定会打交道的一个函数.它看上去非常的简单,朴实.有着一个很不平凡的名字--定时器.让年少的我天真的以为自己可以操纵未来.却不知朴实之中隐含着惊天大密.我还记得我第一次 ...

  2. java.lang.OutOfMemoryError: PermGen space及其解决方法

    PermGen space的全称是Permanent Generation space,是指内存的永久保存区域OutOfMemoryError: PermGen space从表面上看就是内存益出,解决 ...

  3. AlwaysOn与数据库镜像端点问题

    今天在搭建一个测试环境的时候发现一个问题,我将AlwaysOn环境中某节点上的某个非可用性组里的数据库想实时备份到另外一台服务器上,因此我找了一个没有加域的工作组的服务器,与AlwaysOn主节点去搭 ...

  4. progresql - 常用的管理命令

    1.查看当前数据库实例的版本 Select version(); 2.查看数据库的启动时间 Select pg_postmaster_start_time(); 3.查看最后load配置文件的时间 s ...

  5. OC语言-03-OC语言-三大特性

    一.封装 1> 封装的定义 隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别 2> 封装的好处 可以通过set方法防止为成员变量设置不合理的值 仅向外部提供公 ...

  6. [转] - QBuffer类参考

    QBuffer类参考 QBuffer类是一个操作QByteArray的输入/输出设备. 详情请见…… #include <qbuffer.h> 继承了QIODevice. 所有成员函数的列 ...

  7. win7系统中更新错误怎么解决的方法

    不少安装win7旗舰版系统的网友们都喜欢关注微软发布的一些消息,尤其是关于win7旗舰版系统的更新补丁时都会下载并安装的.可是不少网友在自动更新补丁的时遇到自动更新失败的问题,下面来介绍一下具体操作! ...

  8. SchemaExport的使用

    @Test public void testCreateDB(){ Configuration cfg = new Configuration().configure(); SchemaExport ...

  9. SQLServer错误代码解释

    SQLServer出现错误的代码大全(好用) Code Error Message 0 操作成功完成. 1 功能错误. 2 系统找不到指定的文件. 3 系统找不到指定的路径. 4 系统无法打开文件. ...

  10. c# 中日期的使用

    上月第一天:DateTime.Parse(DateTime.Now.AddMonths(-1).ToString("yyyy-MM-01")) 上周星期天:DateTime.Par ...