TableView 跳过一些单元格来显示来自 JSON 的数据

Posted

技术标签:

【中文标题】TableView 跳过一些单元格来显示来自 JSON 的数据【英文标题】:TableView skips a few cells to display data from 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 还是故事板中设计的单元格?如果是后者,则注册单元格是错误的。删除该行。 【参考方案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(), ^...) 调用中

【讨论】:

以上是关于TableView 跳过一些单元格来显示来自 JSON 的数据的主要内容,如果未能解决你的问题,请参考以下文章

如何制作多个表格视图单元格来引导相应的视图控制器?

添加具有行动画的单元格时,将 tableview 保持在相同的滚动位置

IOS Swift TableView:有没有办法将第一个单元格向下移动一行

使用 NSMutableDictionary 和数组填充单元格的 TableView

如何为已添加在 UIViewController 之上的 tableView 添加自定义单元格?

使用 swift 在 tableviewcell 内创建 tableview