• [tableView reloadData] 和 runloop


    需要[tableView reloadData]后需要立即获取tableview的cell、高度,或者需要滚动tableview,那么,直接在reloadData后执行代码是会有问题的。

    断点调试感觉[tableview reloaddata]是个异步操作导致下面的代码并不会再它执行完后才执行。

    于是就想到了多线程,最简单使用动画来延迟执行

    [UIView animateWithDuration:0.3 animations:^{
                [self.collectionView reloadData];
            } completion:^(BOOL finished) {
                [self.collectionView setContentOffset:offset animated:NO];
            }];

    解决是解决了,但是感觉有特别明显的动画效果还是去查了资料才知道是runloop的原因而不是异步问题

    大神解说是因为[tableview reloaddata] 需要在当前方法在runloop中执行完后它再在runloop中执行,处理函数是在runloop中串行的排队执行的。但是[tableview reloaddata]后面的代码需要[tableview reloaddata]的计算结果,所以[tableview reloaddata]后面的代码需要一个延迟执行。只有当前方法不再占用runloop,[tableview reloaddata]才可以在runloop中执行,而这时延迟执行的部分在runloop中早就排在了[tableview reloaddata]的前面执行完了。如果表中的数据非常大,在一个runloop周期没执行完,这时,需要tableview视图数据的操作就会出问题了。apple并没有直接提供reloadData的api,想要程序延迟到reloadData结束再操作,可以用以下方法

    方法1:layoutIfNeeded会强制重绘并等待完成

    [self.tableView reloadData];  
    [self.tableView layoutIfNeeded];  
    //刷新完成  

    方法2:

    reloadData会在主队列执行,而dispatch_get_main_queue会等待机会,直到主队列空闲才执行。

    [self.collectionView reloadData];
    dispatch_async(dispatch_get_main_queue(), ^{
        // 刷新完成
        [self.collectionView setContentOffset:offset animated:NO];
        });
    }

     

     

  • 相关阅读:
    android事件拦截处理机制详解
    序列化
    事件系统的一般性
    Android应用启动、退出分析
    Android Activity.startActivity流程简介
    ActivityThread
    Android Activity学习笔记——Activity的启动和创建
    attachBaseContext
    新认识的类
    深入理解Intent和IntentFiler(一)
  • 原文地址:https://www.cnblogs.com/xs514521/p/5876488.html
Copyright © 2020-2023  润新知