问题场景

这个问题遇到是偶然的,正常来说是不会出现的。但是有时候在一些极端操作情况下,还是出现了。

现在我说明下这个场景。页面上是一个tableview,那对应的有一个dataSource,页面顶部有两个“进行中”“已结束”切换按钮。用户通过切换这两个按钮来拉取不同的数据,但是呢,数据源是同一个。对应的网络请求是一样的,只不过是里面请求参数的status一个是1,一个是2。看下这个页面的网络数据回调处理方式:


if(!self.dataSource) {
self.dataSource = responseObj;
} else {
[self.dataSource.orderList addObjectsFromArray:responseObj.orderList];
} [tableView reload];

这个页面的dataSource真实的类型就是网络请求返回的实体responseObj的类型。tableView的真实数据源就是里面的orderList。上面的代码意思很简单,就是如果dataSource为空说明是第一次加载数据,直接进行赋值。如果不为空,说明是上拉加载更多,因此,只要向orderList数组中添加新的数据,然后reload。这样就完成了tableView的数据源更新。

下面再看下如何发请求的:

//获取进行中的订单
- (void)didGetOngoingOrderButtonClicked:(id)sender
{
self.dataSource = nil;
self.request.status = "1";
[request startWithDelegate:self];
} //获取已经结束的订单
- (void)didGetEndOrderButtonClicked:(id)sender
{
self.dataSource = nil;
self.request.status = "2";
[request startWithDelegate:self];
}

逻辑上都是对的,如果切换先将之前的数据源置为nil,然后重新去拉取切换的状态数据。但是,我用鼠标来回疯狂的切换的时候,发现进行中的数据源里面竟然混杂着已经结束的数据源。一开始找了半天都没发现是什么问题,只知道数据源每次请求之前都置为nil的。怎么可能会出现数据源混乱的问题呢。在仔细看界面显示的数据,都是一段进行中的,一段已经结束的。由此可以确定,我们在网络返回数据处理那边在判断nil的情况时,出现了数据混乱的问题。不过,我们可能会想到,在发起请求的时候,我们会弹出指示器,然后阻止用户继续操作。这样基本都能解决这些问题。但是如果我们的程序是跑在了性能比较差的iphone4上时,就有可能会出现,你指示器还没出现,但是用户以为点了没有反应,于是又疯狂的点了几次,这样就会发出了好几次同样的请求。在网络底层那边,我们可能会过滤掉相同的请求,来避免此问题。对于这样公用一个数据源的情况,而且要处理两个不同的切换状态,如果控制不当,就有可能出现这个问题。

看看解决的办法,只是在请求之前先取消发出去的请求,来保证只允许处理一个转态返回数据:

//获取进行中的订单
- (void)didGetOngoingOrderButtonClicked:(id)sender
{
[self.request cancel];
self.dataSource = nil;
self.request.status = "1";
[request startWithDelegate:self];
} //获取已经结束的订单
- (void)didGetEndOrderButtonClicked:(id)sender
{
[self.request cancel];
self.dataSource = nil;
self.request.status = "2";
[request startWithDelegate:self];
}

这个问题出现的重点是极端情况下发出了两个不同状态的请求,在回调的时候,由于第一个回来的是nil,所以直接赋值。但是第二个回来的时候,因为不是nil,所以直接往数组里面添加数据,导致了数据源混乱的问题。虽然出现情况很特殊,但是也应该引起我们的重视。

最新文章

  1. MySQL MMM高可用方案
  2. WAP站点(IIS/Apache)的服务器设置
  3. jsp实现一条横线中间有字的样式
  4. Android logcat
  5. [学点英语]扎克伯格给女儿的信,translation of zucherber's letter to her daughter( Chinese version)
  6. RequireJS API
  7. 快递查询API接口(trackingmore)
  8. Windows2003 下 MySQL 数据库每天自动备份
  9. oracle常用命令总结
  10. Oracle Locks之DML锁
  11. WPF Image触摸移动方法
  12. Linux基本命令(开发常用的、电脑常用的)
  13. js防堵塞载入
  14. 每天一个Linux命令 8
  15. 编写高质量代码改善程序的157个建议:使用Dynamic来简化反射的实现
  16. Spring mybatis源码篇章-XMLLanguageDriver解析sql包装为SqlSource
  17. 复制pdf文字出来是乱码
  18. c++实现 给定直角停车位两个点,求取剩余两点坐标。
  19. DB操作-用批处理执行Sql语句
  20. jsonp的工作原理

热门文章

  1. 002-guava String 操作
  2. python3-sql解析库——sqlparse
  3. 软件定义网络基础---NETCONF协议
  4. 【serviceaccount 和 clusterrolebinding】
  5. [转]Ubuntu安装ss客户端
  6. 【GStreamer开发】GStreamer播放教程03——pipeline的快捷访问
  7. 十篇TED点击率最高演讲,带你重新认识大数据与人工智能
  8. [转帖]两种以太网 RDMA 协议: iWARP 和 RoCE
  9. 【转帖】DevOps和SRE的区别
  10. Windows 下配置 ApacheBench (AB) 压力测试