真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

分析ios監(jiān)聽(tīng)reloadData刷新列表完畢的時(shí)機(jī)

本篇內(nèi)容介紹了“分析ios監(jiān)聽(tīng)reloadData刷新列表完畢的時(shí)機(jī)”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

10年積累的成都網(wǎng)站建設(shè)、做網(wǎng)站經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有貢覺(jué)免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

分析:

reloadData 是一個(gè)異步方法,并不會(huì)等待 UITableView 或者 UICollectionView (后面統(tǒng)稱 listView )真正刷新完畢后才執(zhí)行后續(xù)代碼,而是立即執(zhí)行后續(xù)代碼。我們執(zhí)行 reloadData 的本意是刷新 listView ,隨后會(huì)進(jìn)入一系列的DataSource和Delegate回調(diào),有些是和reloadData同步發(fā)生的,有些是異步發(fā)生的。

同步: numberOfSectionsInCollectionView 和 numberOfItemsInSection異步: cellForItemAtIndexPath同步+異步: sizeForItemAtIndexPath

問(wèn)題:

由于cell復(fù)用的原因,直接在 reloadData 后執(zhí)行代碼是有可能出問(wèn)題的。比如在 reloadData 前保留了一個(gè)cell,在 reloadData 后,對(duì)這個(gè)cell(已經(jīng)不是原來(lái)的cell了)進(jìn)行某些操作,會(huì)出現(xiàn)一些異常問(wèn)題。

解決辦法:

在 reloadData 前不是保留cell,二是保留當(dāng)前cell對(duì)應(yīng)的 NSIndexPath ,然后在 reloadData 完畢( listView 真正刷新完畢)后通過(guò)方法 cellForItemAtIndexPath: 重新獲取cell,然后進(jìn)行相應(yīng)的操作。

獲取listView真正刷新完畢的時(shí)機(jī)的幾種方法

方法1、通過(guò)layoutIfNeeded方法,強(qiáng)制重繪并等待完成。

[self.collectionView reloadData];[self.collectionView layoutIfNeeded];// 刷新完成,執(zhí)行后續(xù)需要執(zhí)行的代碼if ( self.didPlayIdx ) {  MyCell* cell = (MyCell*)[self.collectionView cellForItemAtIndexPath:self.didPlayIdx];  if (cell) { [cell playWithPlayer:self.player];  }}

方法2、 reloadData 方法會(huì)在主線程執(zhí)行,通過(guò)GCD,使后續(xù)操作排隊(duì)在 reloadData 后面執(zhí)行。一次runloop有兩個(gè)機(jī)會(huì)執(zhí)行GCD dispatch main queue中的任務(wù),分別在休眠前和被喚醒后。設(shè)置 listView 的 layoutIfNeeded 為YES,在即將進(jìn)入休眠時(shí)執(zhí)行異步任務(wù),重繪一次界面。

[self.collectionView reloadData];dispatch_async(dispatch_get_main_queue(), ^{  // 刷新完成,執(zhí)行后續(xù)代碼  if ( self.didPlayIdx ) {    MyCell* cell = (MyCell*)[self.collectionView cellForItemAtIndexPath:self.didPlayIdx];    if (cell) {      [cell playWithPlayer:self.player];    }  }});

知識(shí)點(diǎn)關(guān)聯(lián):GCD死鎖、Runloop

// 發(fā)生死鎖,永遠(yuǎn)不會(huì)執(zhí)行任務(wù)2和3NSLog(@"1");dispatch_sync(dispatch_get_main_queue(), ^{  NSLog(@"2");});NSLog(@"3");

方法3、自定義UICollectionView、UITableView,layoutSubviews之后當(dāng)作reloadData完成(復(fù)雜,但可以更好的理解方法一)

#import "MyTableView.h"@interface MyTableView()@property (nonatomic, copy) void (^reloadDataCompletionBlock)();@end@implementation MyTableView- (void)reloadDataWithCompletion:(void (^)())completionBlock {  self.reloadDataCompletionBlock = completionBlock;  [super reloadData];}- (void)layoutSubviews {  [super layoutSubviews];  if (self.reloadDataCompletionBlock) {    self.reloadDataCompletionBlock();    self.reloadDataCompletionBlock = nil;  }}@end// 調(diào)用的時(shí)候[self.tableView reloadDataWithCompletion:^{   NSLog(@"完成刷新");}];

引申:更新UI放在主線程的原因

原因一:安全+效率

因?yàn)閁IKit框架不是線程安全的,當(dāng)多個(gè)線程同時(shí)操作UI的時(shí)候,搶奪資源,導(dǎo)致崩潰,UI異常等問(wèn)題。假如在兩個(gè)線程中設(shè)置了同一張背景圖片,很有可能就會(huì)由于背景圖片被釋放兩次,使得程序崩潰?;蛘吣骋粋€(gè)線程中遍歷找尋某個(gè)subView,然而在另一個(gè)線程中刪除了該subView,那么就會(huì)造成錯(cuò)亂。apple有對(duì)大部分的繪圖方法和諸如UIColor等類改寫(xiě)成線程安全可用,可還是建議將UI操作保證在主線程中。例如說(shuō),我們需要在子線程中讀取一個(gè)image對(duì)象,使用接口 [UIImage imageNamed:] ,但 imageNamed: 實(shí)際上在 iOS9 以后才是線程安全的, iOS9 之前都需要在主線程獲取。所以,我們需要從子線程切換到主線程獲取image,然后再切回子線程拿到這個(gè)image,這里我們必須使用sync。

__block UIImage *image;dispatch_sync_on_main_queue(^{  image = [UIImage imageNamed:@"Resource/img"];});attachment.image = image;// YYKit中提供了一個(gè)同步扔任務(wù)到主線程的安全方法:/** Submits a block for execution on a main queue and waits until the block completes.*/static inline void dispatch_sync_on_main_queue(void (^block)()) {  if (pthread_main_np()) {    block();  } else {    dispatch_sync(dispatch_get_main_queue(), block);  }}

原因二:用戶體驗(yàn)

iOS中只有主線程才能立即刷新UI。在子線程中是不能夠更新UI,我們看到的子線程能夠更新UI的原因是,等到子線程執(zhí)行完畢,自動(dòng)進(jìn)入了主線程去執(zhí)行子線程中更新UI的代碼。由于子線程執(zhí)行時(shí)間非常短暫,讓我們誤以為子線程可以更新UI。如果子線程一直在運(yùn)行,則無(wú)法更新UI,因?yàn)闆](méi)有辦法進(jìn)入主線程。

“分析ios監(jiān)聽(tīng)reloadData刷新列表完畢的時(shí)機(jī)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!


網(wǎng)頁(yè)題目:分析ios監(jiān)聽(tīng)reloadData刷新列表完畢的時(shí)機(jī)
瀏覽路徑:http://weahome.cn/article/jdedjs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部