[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];
    });
}

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM