【问题标题】:TableView skips a few cells to display data from JSONTableView 跳过一些单元格来显示来自 JSON 的数据
【发布时间】:2017-10-13 16:05:26
【问题描述】:

所以我可以解析 JSON 数据,但是当我尝试在 TableView 中显示它时,我会显示第一行,然后可能是第六个数据,依此类推,如下所示:

这就是我检索数据的方式:

- (void)getData{

    NSURL *url = [NSURL URLWithString:@"https://gist.githubusercontent.com/hart88/198f29ec5114a3ec3460/raw/8dd19a88f9b8d24c23d9960f3300d0c917a4f07c/cake.json"];

    NSData *data = [NSData dataWithContentsOfURL:url];

    NSError *jsonError;
    id responseData = [NSJSONSerialization
                       JSONObjectWithData:data
                       options:kNilOptions
                       error:&jsonError];
    if (!jsonError){
        self.objects = responseData;
        NSLog(@"%@", self.objects);
        [self.tableView reloadData];
    } else {
    }

}

这就是我在 cellforRowAt 中显示它们的方式:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CakeCell *cell = (CakeCell*)[tableView dequeueReusableCellWithIdentifier:@"CakeCell"];
[self.tableView registerClass:[CakeCell self] forCellReuseIdentifier:@"CakeCell"];

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(queue, ^(void) {

    NSDictionary *object = self.objects[indexPath.row];
    cell.titleLabel.text = object[@"title"];
    cell.descriptionLabel.text = object[@"desc"];


    NSURL *aURL = [NSURL URLWithString:object[@"image"]];
    NSData *data = [NSData dataWithContentsOfURL:aURL];
    UIImage *image = [UIImage imageWithData:data];
    [cell.cakeImageView setImage:image];

});

return cell;
}

【问题讨论】:

  • 为什么要发送到cellForRow?只需使用主线程,您不应该访问后台线程中的单元格。这可能就是那里的原因。
  • @libec 我使用它们来避免滚动 tableView 时出现延迟。即使我不使用调度,我仍然有同样的问题。
  • 你能把剩下的代码贴出来吗?
  • 从不cellForRow 中注册单元,并且在(重新)使用它们之后从不注册单元。如果您不使用额外的 XIB,则根本不要注册单元。另一个不要是:不要在cellForRow中与[NSData dataWithContents同步加载数据
  • 你使用额外的 XIB 还是故事板中设计的单元格?如果是后者,则注册单元格是错误的。删除该行。

标签: ios objective-c json uitableview


【解决方案1】:

问题是您从后台线程访问 UIKit 元素。您可以通过以下方式对其进行重构。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CakeCell *cell = (CakeCell*)[tableView dequeueReusableCellWithIdentifier:@"CakeCell"];
    [self.tableView registerClass:[CakeCell self] forCellReuseIdentifier:@"CakeCell"];

    NSDictionary *object = self.objects[indexPath.row];
    cell.titleLabel.text = object[@"title"];
    cell.descriptionLabel.text = object[@"desc"];

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_async(queue, ^(void) {        
        NSURL *aURL = [NSURL URLWithString:object[@"image"]];
        NSData *data = [NSData dataWithContentsOfURL:aURL];
        UIImage *image = [UIImage imageWithData:data];

        dispatch_async(dispatch_get_main_queue(), ^{
            [cell.cakeImageView setImage:image];
        });        
    });    
    return cell;
}


如果由于后台操作而需要从某些 UI 更新中进行操作,请始终将此代码包装在 dispatch_async(dispatch_get_main_queue(), ^{...}) 调用中

【讨论】:

    猜你喜欢
    • 2020-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多