Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Analyze the time when ios snooping reloadData refreshes the list

2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

本篇内容介绍了"分析ios监听reloadData刷新列表完毕的时机"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

分析:

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

方法2、 reloadData 方法会在主线程执行,通过GCD,使后续操作排队在 reloadData 后面执行。一次runloop有两个机会执行GCD dispatch main queue中的任务,分别在休眠前和被唤醒后。设置 listView 的 layoutIfNeeded 为YES,在即将进入休眠时执行异步任务,重绘一次界面。

[self.collectionView reloadData];dispatch_async(dispatch_get_main_queue(), ^{ // 刷新完成,执行后续代码 if ( self.didPlayIdx ) { MyCell* cell = (MyCell*)[self.collectionView cellForItemAtIndexPath:self.didPlayIdx]; if (cell) { [cell playWithPlayer:self.player]; } }});

知识点关联:GCD死锁、Runloop

// 发生死锁,永远不会执行任务2和3NSLog(@"1");dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"2");});NSLog(@"3");

方法3、自定义UICollectionView、UITableView,layoutSubviews之后当作reloadData完成(复杂,但可以更好的理解方法一)

#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// 调用的时候[self.tableView reloadDataWithCompletion:^{ NSLog(@"完成刷新");}];

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

原因一:安全+效率

因为UIKit框架不是线程安全的,当多个线程同时操作UI的时候,抢夺资源,导致崩溃,UI异常等问题。假如在两个线程中设置了同一张背景图片,很有可能就会由于背景图片被释放两次,使得程序崩溃。或者某一个线程中遍历找寻某个subView,然而在另一个线程中删除了该subView,那么就会造成错乱。apple有对大部分的绘图方法和诸如UIColor等类改写成线程安全可用,可还是建议将UI操作保证在主线程中。例如说,我们需要在子线程中读取一个image对象,使用接口 [UIImage imageNamed:] ,但 imageNamed: 实际上在 iOS9 以后才是线程安全的, iOS9 之前都需要在主线程获取。所以,我们需要从子线程切换到主线程获取image,然后再切回子线程拿到这个image,这里我们必须使用sync。

__block UIImage *image;dispatch_sync_on_main_queue(^{ image = [UIImage imageNamed:@"Resource/img"];});attachment.image = image;// YYKit中提供了一个同步扔任务到主线程的安全方法:/** 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); }}

原因二:用户体验

iOS中只有主线程才能立即刷新UI。在子线程中是不能够更新UI,我们看到的子线程能够更新UI的原因是,等到子线程执行完毕,自动进入了主线程去执行子线程中更新UI的代码。由于子线程执行时间非常短暂,让我们误以为子线程可以更新UI。如果子线程一直在运行,则无法更新UI,因为没有办法进入主线程。

"分析ios监听reloadData刷新列表完毕的时机"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report