简体   繁体   English

数据源为空时,UITableView调用委托方法

[英]UITableView calling delegate method when datasource is empty

I've got my cellForRowAtIndexPath delegate method defined as so: 我已经将cellForRowAtIndexPath委托方法定义为:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    PLOTCheckinTableViewCell *cell = (PLOTCheckinTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CheckinCellIdentifier forIndexPath:indexPath];
    if([self.items count] == 0){
        return cell;
    }
    NSDictionary *checkin = self.items[indexPath.row];
    // configure and return custom cell
}

I'm using a custom cell class ( PLOTCheckinTableViewCell ). 我正在使用自定义单元格类( PLOTCheckinTableViewCell )。

I faced an issue where the user would pull to refresh and then attempt to pull again before the first request had completed (on completion of the request, I reload the table data). 我遇到了一个问题,用户将拉动刷新,然后尝试在第一个请求完成之前再次拉动(在请求完成后,我重新加载表数据)。 When they did this, the app would crash and say that indexPath.row was basically out of bounds, ie. 当他们这样做时,应用程序将崩溃,并说indexPath.row基本上超出范围,即。 the array was empty. 数组为空。

By putting in this IF check above, I mitigated the crash. 通过在上面进行此IF检查,我缓解了崩溃。

However, 然而,

  1. Why exactly does my IF check "work", I see no visual implications of returning the cell before it's been configured. 为什么我的IF精确地检查“工作”,我看不到在配置单元之前返回单元的视觉影响。 This is confusing 这很混乱

  2. Are there any better ways to guard against this happening (ie. the table data being reloaded with an empty array)? 有没有更好的方法来防止这种情况发生(即,用空数组重新加载表数据)? Surely the numberOfRowsInSection would have returned array count which would be 0? 肯定numberOfRowsInSection将返回array count为0? (if it was an empty array) (如果它是一个空数组)

EDIT (further code) 编辑(更多代码)

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    float count = [self.items count];
    return count;
}

- (void)resetData {
    self.items = [NSMutableArray array];
}

-(void) refreshInvoked:(id)sender forState:(UIControlState)state {
    [self resetData];
    [self downloadHomeTimeline];
    [self.refreshControl endRefreshing];
}

- (void)downloadHomeTimeline {
    [self.apiClient homeTimeline:self.page completionBlock:^(NSDictionary *data){
        for (NSDictionary *obj in data[@"items"]) {
            [self.items addObject:obj];
        }
        [self.itemsTableView reloadData];
    }];
}

I couple of things that i would suggest to do. 我建议做几件事。 Make sure that the [self.itemsTableView reloadData] is executed on the main thread and also i would put the [self.refresControl endRefreshing] in the completion block. 确保[self.itemsTableView reloadData]在主线程上执行,并且我也将[self.refresControl endRefreshing]放在完成块中。 This way it will stop the refresh when its done and you should not let the user more then once simultaneously. 这样,刷新完成后它将停止刷新,您不应再让用户再进行一次刷新。

 - (void)downloadHomeTimeline {
        [self.apiClient homeTimeline:self.page completionBlock:^(NSDictionary *data){
            for (NSDictionary *obj in data[@"items"]) {
                [self.items addObject:obj];
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.itemsTableView reloadData];
                [self.refreshControl endRefreshing];
             }); 

        }];
    }

Also in the numberOfRowsInSection just return count 同样在numberOfRowsInSection只是返回计数

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [self.items count];
}

To add to the answer. 添加到答案。 You should not reset the array before you receive new data. 接收新数据之前,请勿重置阵列。 While getting new data the user can still scroll the table and that means new cells will be created but your NSMutableArray doesn't have any data. 在获取新数据时,用户仍然可以滚动表,这意味着将创建新的单元格,但您的NSMutableArray没有任何数据。 That is when you get the error and app crashes. 那是当您收到错误并且应用程序崩溃时。 You would have to [tableView reloadData] to clear the table so that the tableView would know that there are 0 rows, which i don't think is your intent. 您将必须[tableView reloadData]清除表,以便tableView知道有0行,我认为这不是您的意图。

Let me know if that's solves the issue. 让我知道是否可以解决问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM