分析:
reloadData 是一个异步方法,并不会等待 UITableView 或者 UICollectionView (后面统称 listView )真正刷新完毕后才执行后续代码,而是立即执行后续代码。我们执行 reloadData 的本意是刷新 listView ,随后会进入一系列的DataSource和Delegate回调,有些是和reloadData同步发生的,有些是异步发生的。
- 同步: numberOfSectionsInCollectionView 和 numberOfItemsInSection
- 异步: cellForItemAtIndexPath
-
同步+异步: sizeForItemAtIndexPath
问题:
由于cell复用的原因,直接在 reloadData 后执行代码是有可能出问题的。比如在 reloadData 前保留了一个cell,在 reloadData 后,对这个cell(已经不是原来的cell了)进行某些操作,会出现一些异常问题。
解决办法:
在 reloadData 前不是保留cell,二是保留当前cell对应的 NSIndexPath ,然后在 reloadData 完毕( listView 真正刷新完毕)后通过方法 cellForItemAtIndexPath: 重新获取cell,然后进行相应的操作。
获取listView真正刷新完毕的时机的几种方法
方法1、通过layoutIfNeeded方法,强制重绘并等待完成。
[self.collectionView reloadData]; [self.collectionView layoutIfNeeded]; // 刷新完成,执行后续需要执行的代码 if ( self.didPlayIdx ) { MyCell* cell = (MyCell*)[self.collectionView cellForItemAtIndexPath:self.didPlayIdx]; if (cell) { [cell playWithPlayer:self.player]; } }










