手记

iOS学习笔记--新老Coder易忽略的分页请求

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

- (void)viewDidLoad {
    [super viewDidLoad];
    [self tableView];
    self.pageNum = 1;
    self.dataArray = [NSMutableArray arrayWithCapacity:0];
    [self.tableView reloadDataForHeaderAction:@selector(refreshData) footerAction:@selector(loadMoreData) andTarget:self];
    [self requestData];
}
- (void)refreshData
{
    self.pageNum = 1;
    [self requestData];
}

-(void)loadMoreData
{
    self.pageNum ++;
    [self requestData];
}
- (void)requestData
{
    NSString *memberId = [kUserDefaults objectForKey:ZHMemberId];
    NSString *url = [NSString stringWithFormat:@"%@%@?memberId=%@&%@&removeHtmlTag=true", kAppBaseUrl, personalMessageList,SafeStr(memberId), KPageStringWithPage(self.pageNum)];
    [self.netModel getWithUrl:url successBlock:^(ZHNetModel *resultModel) {
        [self.tableView endMJRefreshing];
        if (resultModel.status == networkSuccessStatus) {
            if (self.pageNum == 1) {
                [self.dataArray removeAllObjects];
            }
            NSArray *data = resultModel.datas;
            if (data && [data isKindOfClass:[NSArray class]]) {
                [self.dataArray addObjectsFromArray:[ZHPersonalMessageModel mj_objectArrayWithKeyValuesArray:data]];
                [self.tableView reloadData];
            }
//            [self.tableView showOrHideNoDataView:!data.count];
        }
    } failedBlock:^(NSError *error) {
        [self.tableView endMJRefreshing];
    }];

}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.dataArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    BCMyMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([BCMyMessageCell class]) forIndexPath:indexPath];
    cell.msgModel = self.dataArray[indexPath.row];
    return cell;
}

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

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

0人推荐
随时随地看视频
慕课网APP