查看: 165|回复: 0

[IOS开发教程] iOS学习笔记--新老Coder易忽略的分页请求

发表于 2018-5-8 08:00:06

作为一个快四年的ios开发,最近犯了个低级错误,如下的分页TableView,我会在代码下面说出错误点、原因和解决办法

  1. - (void)viewDidLoad {
  2. [super viewDidLoad];
  3. [self tableView];
  4. self.pageNum = 1;
  5. self.dataArray = [NSMutableArray arrayWithCapacity:0];
  6. [self.tableView reloadDataForHeaderAction:@selector(refreshData) footerAction:@selector(loadMoreData) andTarget:self];
  7. [self requestData];
  8. }
  9. - (void)refreshData
  10. {
  11. self.pageNum = 1;
  12. [self requestData];
  13. }
  14. -(void)loadMoreData
  15. {
  16. self.pageNum ++;
  17. [self requestData];
  18. }
  19. - (void)requestData
  20. {
  21. NSString *memberId = [kUserDefaults objectForKey:ZHMemberId];
  22. NSString *url = [NSString stringWithFormat:@"%@%@?memberId=%@&%@&removeHtmlTag=true", kAppBaseUrl, personalMessageList,SafeStr(memberId), KPageStringWithPage(self.pageNum)];
  23. [self.netModel getWithUrl:url successBlock:^(ZHNetModel *resultModel) {
  24. [self.tableView endMJRefreshing];
  25. if (resultModel.status == networkSuccessStatus) {
  26. if (self.pageNum == 1) {
  27. [self.dataArray removeAllObjects];
  28. }
  29. NSArray *data = resultModel.datas;
  30. if (data && [data isKindOfClass:[NSArray class]]) {
  31. [self.dataArray addObjectsFromArray:[ZHPersonalMessageModel mj_objectArrayWithKeyValuesArray:data]];
  32. [self.tableView reloadData];
  33. }
  34. // [self.tableView showOrHideNoDataView:!data.count];
  35. }
  36. } failedBlock:^(NSError *error) {
  37. [self.tableView endMJRefreshing];
  38. }];
  39. }
复制代码
  1. -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  2. {
  3. return self.dataArray.count;
  4. }
  5. -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  6. {
  7. BCMyMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([BCMyMessageCell class]) forIndexPath:indexPath];
  8. cell.msgModel = self.dataArray[indexPath.row];
  9. return cell;
  10. }
复制代码

失误现象:暴力下拉MJ的头部刷新会出现程序闪退,原因数组越界,上面的代码是我已经改成正确的。
失误重点:[self.dataArray removeAllObjects];的时机,之前我是放在refreshData方法里面的。
数组越界原因:网络请求是异步的,当我暴力刷新的时候会出现一种情况:前一次刷新的网络请求已经开始,但是数据还未返回的时候我开始了下一次的下拉刷新,上次的请求数据也在这个时刻返回了,开始通知TableView刷新,先走返回cell个数的方法:numberOfRowsInSection,暴力刷新总有一次会恰好在这个时刻数组清空了,但是tableView会在方法cellForRowAtIndexPath里根据下标访问数组,这个时候数组是空的,所以就数组越界,APP崩溃闪退。
解决办法:如上代码,在请求返回数据返回后判断是不是pageNum=1的刷新,再清空数组,这样保证不会出现数组越界。

后记:如果你没出现过或者没考虑过,记住别忽略。但是这个情况是真实存在的。



回复

使用道具 举报