欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2018年11月23日 15:08:10   作者:花丶滿(mǎn)樓  
這篇文章主要介紹了詳解ios監(jiān)聽(tīng)reloadData刷新列表完畢的時(shí)機(jī),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

分析:

reloadData 是一個(gè)異步方法,并不會(huì)等待 UITableView 或者 UICollectionView (后面統(tǒng)稱(chē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ì)在主線(xiàn)程執(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和3
NSLog(@"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放在主線(xiàn)程的原因

原因一:安全+效率

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

__block UIImage *image;
dispatch_sync_on_main_queue(^{
  image = [UIImage imageNamed:@"Resource/img"];
});
attachment.image = image;

// YYKit中提供了一個(gè)同步扔任務(wù)到主線(xiàn)程的安全方法:
/**
 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);
  }
}

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

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 99%?iOS開(kāi)發(fā)都不知道的KVO崩潰分析詳解

    99%?iOS開(kāi)發(fā)都不知道的KVO崩潰分析詳解

    這篇文章主要為大家介紹了99%?iOS開(kāi)發(fā)都不知道的KVO崩潰分析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • iOS中狀態(tài)欄的基本使用方法匯總

    iOS中狀態(tài)欄的基本使用方法匯總

    在iOS開(kāi)發(fā)過(guò)程中,經(jīng)常會(huì)設(shè)置狀態(tài)欄的樣式,所以下面這篇文章主要給大家介紹了關(guān)于iOS中狀態(tài)欄的基本使用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-07-07
  • 講解iOS開(kāi)發(fā)中對(duì)音效和音樂(lè)播放的簡(jiǎn)單實(shí)現(xiàn)

    講解iOS開(kāi)發(fā)中對(duì)音效和音樂(lè)播放的簡(jiǎn)單實(shí)現(xiàn)

    這篇文章主要介紹了iOS開(kāi)發(fā)中對(duì)音效和音樂(lè)播放的簡(jiǎn)單實(shí)現(xiàn),代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下
    2015-11-11
  • iOS開(kāi)發(fā)教程之自定制圖片瀏覽器

    iOS開(kāi)發(fā)教程之自定制圖片瀏覽器

    最近發(fā)現(xiàn)許多常用的APP都有圖片瀏覽器,于是想仿照著自己寫(xiě)一個(gè),下面這篇文章主要給大家介紹了關(guān)于iOS開(kāi)發(fā)教程之自定制圖片瀏覽器的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。
    2017-12-12
  • iOS小技能之字典轉(zhuǎn)模及對(duì)象相等性示例詳解

    iOS小技能之字典轉(zhuǎn)模及對(duì)象相等性示例詳解

    這篇文章主要為大家介紹了iOS小技能之字典轉(zhuǎn)模及對(duì)象相等性示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • IOS CocoaPods詳解之制作篇

    IOS CocoaPods詳解之制作篇

    學(xué)會(huì)使用別人的Pods依賴(lài)庫(kù)以后,你一定對(duì)創(chuàng)建自己的依賴(lài)庫(kù)躍躍欲試,今天就來(lái)揭開(kāi)Pods依賴(lài)庫(kù)創(chuàng)建過(guò)程的神秘面紗
    2016-09-09
  • iOS實(shí)現(xiàn)背景滑動(dòng)效果

    iOS實(shí)現(xiàn)背景滑動(dòng)效果

    這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)背景滑動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • iOS實(shí)現(xiàn)滑動(dòng)弧形菜單的思路與方法

    iOS實(shí)現(xiàn)滑動(dòng)弧形菜單的思路與方法

    這篇文章主要給大家介紹了利用iOS實(shí)現(xiàn)滑動(dòng)弧形菜單的思路與方法,實(shí)現(xiàn)后的效果非常不錯(cuò),非常適合大家在開(kāi)發(fā)中使用,文末給出了封裝源碼下載的地址供大家下載學(xué)習(xí),需要的朋友可以參考,下面來(lái)一起看看吧。
    2017-05-05
  • CocoaPods 出現(xiàn)LoadError - cannot load such file -- nanaimo錯(cuò)誤解決辦法

    CocoaPods 出現(xiàn)LoadError - cannot load such file -- nanaimo錯(cuò)誤解決

    這篇文章主要介紹了CocoaPods 出現(xiàn)LoadError - cannot load such file -- nanaimo錯(cuò)誤解決辦法的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • cmake ios終端下執(zhí)行提示錯(cuò)誤 iOS version not found, tested: [5.0;5.1;6.0;6.1;7.0;8.3]的解決方案

    cmake ios終端下執(zhí)行提示錯(cuò)誤 iOS version not found, tested: [5.0;5.1;6

    這篇文章主要介紹了cmake ios終端下執(zhí)行提示錯(cuò)誤 iOS version not found, tested: [5.0;5.1;6.0;6.1;7.0;8.3]的解決方案的相關(guān)資料,需要的朋友可以參考下
    2016-10-10

最新評(píng)論