iOS开发中的异步网络框架OC的AFNetworking及Swift的Alamofire是我们大多数项目中使用的, 也有公司使用自己网络请求框架. 谈到网络请求,肯定离不开同步还有异步, 同步和异步是基础的编程概念, 也是我们我们再开发中经常用到的.
UITableView,UICollectionView
对于UITableview的使用, 大家肯定是熟悉的,在同步的情况下我们是很少出现问题的. 问题就出现在异步的情况下, 我们可能会出现这样或者那样的错误.(同理UICollectionView也是一样的,以UITableView举例)
具体来说, 就是reloadData这个调用中所包含的异步操作. 先来看看执行reloadData都发生了什么.
当我们reloadData的时候, 我们本意是刷新UITableView, 随后会进入一系列UITableViewDataSource和UITableViewDelegate的回调,其中有些是和reloadData同步发生的, 有些则是异步发生的.
同步:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
异步:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
很明显在cellForRowAtIndexPath的时候, cell的状态可能会发生变化, 我们在异步接收到刷新数据时reloadData. UITableview的数据源数组肯定被修改过, 这时候, 极有可能出现数组越界的异常,导致程序crash.
当列表界面数据不怎么变化的时候, 几乎感知不到这种异常的存在, 因为reloadData返回之后, 下一次loop就开始执行异步的操作了. 但是当列表界面的数据有可能经常变化的时候, 尤其是在多线程的场景下, 就会出现偶现的bug了.
解决
方法一
对刷新方法进行控制
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(_dataArray.count > 0)....
}
方法二
为刷新添加队列queue, 频繁的调用reloadData还会造成界面的卡顿, 所以此时建立一个Queue, 这样既保证了刷新,也会使界面不会出现各种卡顿的问题, 这种方法比上面复杂一点, 但是在实际运用中肯定会更加安全.
方法三
暂时想不到了,肯定有更好的解决办法等待着我们的发现...
UIButton
UIButton也是我们的老熟人, 大家肯定对他都很熟悉, 多的废话也就没必要说了, 个人认为, UIButton这个控件我是非常喜欢的. 在这里介绍给大家一个它的set方法.
[btn setExclusiveTouch:YES];
我们可以command+单击进入里面看看
介个set方法的作用是: 避免在一个界面上同时点击多个button, 即同时点击button1和button2.有兴趣的小伙伴可以试试会出现什么问题```
分享结束,谢谢大家,希望能够共同进步!
开源```还是开源```