使用 GCD 异步 UITableViewCell 图像加载

2024-05-09

我目前正在尝试加载 Flickr 照片的 UITableView 列表(cs193p iOS 斯坦福大学,作业 5)。为了避免 UI 阻塞事件,我将每个单元格的缩略图下载推迟到不同的队列中(但确实将 UI 更新回主队列中)。此代码不会异步加载图像,但在单击 UITableViewCell 行后会添加缩略图。 (参见下面的屏幕截图)。知道我做错了什么吗?

PS:我已经查看了其他一些 stackoverflow 问题和 Apple 的 LazyTableImages 示例,但我仍然相信这是实现所需结果的最干净的方法。

Thanks!

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Photo List Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Configure the cell
    NSDictionary *photo = [self.photoList objectAtIndex:indexPath.row];


    if (photo != nil) {
        if ([[photo objectForKey:@"title"] length] > 0) {
            cell.textLabel.text = [photo objectForKey:@"title"];
        } else if ([[[photo objectForKey:@"description"] objectForKey:@"_content"] length] > 0) {
            cell.textLabel.text = [[photo objectForKey:@"description"] objectForKey:@"_content"];
        } else {
            cell.textLabel.text = @"Unknown";
        }
    }
    cell.imageView.image = [[UIImage alloc] initWithCIImage:nil];

    // Fetch using GCD
    dispatch_queue_t downloadThumbnailQueue = dispatch_queue_create("Get Photo Thumbnail", NULL);
    dispatch_async(downloadThumbnailQueue, ^{
        UIImage *image = [self getTopPlacePhotoThumbnail:photo];
        dispatch_async(dispatch_get_main_queue(), ^{
            if ([self.tableView.visibleCells containsObject:cell]) {
                [cell.imageView setImage:image];
            }
        });
    });
    dispatch_release(downloadThumbnailQueue);

    return cell;
}

Before clicking a row Before clicking a row

After selecting the row After selecting the row

更新:对于那些感兴趣的人,这是我使用的最终代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  static NSString *CellIdentifier = @"Photo List Cell";
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

  // Configure the cell
  NSDictionary *photo = [self.photoList objectAtIndex:indexPath.row];

  if (photo != nil) {
    if ([[photo objectForKey:@"title"] length] > 0) {
        cell.textLabel.text = [photo objectForKey:@"title"];
    } else if ([[[photo objectForKey:@"description"] objectForKey:@"_content"] length] > 0) {
        cell.textLabel.text = [[photo objectForKey:@"description"] objectForKey:@"_content"];
    } else {
        cell.textLabel.text = @"Unknown";
    }
  }
  cell.imageView.image = [[UIImage alloc] initWithCIImage:nil];

  // Fetch using GCD
  dispatch_queue_t downloadThumbnailQueue = dispatch_queue_create("Get Photo Thumbnail", NULL);
  dispatch_async(downloadThumbnailQueue, ^{
    UIImage *image = [self getTopPlacePhotoThumbnail:photo];
    dispatch_async(dispatch_get_main_queue(), ^{
        UITableViewCell *cellToUpdate = [self.tableView cellForRowAtIndexPath:indexPath]; // create a copy of the cell to avoid keeping a strong pointer to "cell" since that one may have been reused by the time the block is ready to update it. 
        if (cellToUpdate != nil) {
            [cellToUpdate.imageView setImage:image];
            [cellToUpdate setNeedsLayout];
        }
    });
  });
  dispatch_release(downloadThumbnailQueue);

  return cell;
}

你应该打电话setNeedsLayout设置缩略图后在单元格上。

来自苹果文档:

“当您想要调整视图子视图的布局时,请在应用程序的主线程上调用此方法。此方法会记录请求并立即返回。因为此方法不会强制立即更新,而是等待下一次更新周期,您可以使用它在更新任何视图之前使多个视图的布局无效。这种行为允许您将所有布局更新合并到一个更新周期,这通常更有利于性能。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 GCD 异步 UITableViewCell 图像加载 的相关文章

  • 禁用选择单个 UITableViewCell

    如何禁止在 UITableView 中仅选择单个单元格 我有几个 我只想禁用最后一个 要停止仅选择某些单元格 请使用 cell userInteractionEnabled NO 除了阻止选择之外 这还会阻止为设置了该选项的单元格调用 ta
  • 在 Swift UI 中为文本添加动画

    怎么可能动画化Text or TextField来自 Swiftui 的意见 我所说的动画是指 当文本发生变化时 它会 计数 例如 给定一些标签 如何创建一个动画 当我将标签文本设置为 100 时 它会从 0 上升到 100 我知道这在 U
  • 使用accesskey和secretkey从S3服务器下载安全文件

    我正在尝试使用 NSURLSessionDownloadTask 从 S3 服务器下载安全文件 但它返回 403 错误 访问被拒绝 My Code NSMutableURLRequest request NSMutableURLReques
  • UITextfield 键盘只有字母,没有数字,没有大写字母,没有空格键?

    我希望 UITextfield 的键盘只有 a z 没有数字 没有特殊字符 并且没有大写字母 基本上我想要一个只有字母的键盘 我已经能够禁用该空间了 有人知道如何禁用数字 特殊字符和大写字母吗 解决这些问题中的任何一个都很棒 对所有角色执行
  • 如何使用文档提供者扩展?

    我正在学习更多有关 ios 扩展的知识 例如 今日扩展 照片编辑扩展 动作延伸 自定义键盘扩展 在所有这些中 我在学习上没有困难 但最近我尝试学习 文档提供程序扩展 令我惊讶的是 在互联网上没有找到任何相关教程谈论如何使用它 与其他人一样一
  • 4.4 中新的 Objective-c 文字

    我可以写 42 这会创建一个NSNumber with int值 42 我可以用变量来做到这一点 例如 someIntVar 显然我尝试过但它不起作用 这很糟糕 因为然后我必须经历 NSNumber numberWithInt someIn
  • 统一的阿拉伯语输入字段

    有没有办法将输入字段的语言统一更改为阿拉伯语 我尝试了ArabicSupport 它正确显示了阿拉伯语 但将其与输入字段一起使用却不起作用 因为 GameObject Find input field GetComponent
  • FB SDK 3.0 我是否需要扩展访问令牌还是自动的?

    基于http developers facebook com roadmap offline access removal http developers facebook com roadmap offline access remova
  • 当 tableview 滚动时 UISegment 值发生变化

    我正在使用 UISegmentControl 在表格视图中显示客观类型问题 但是 如果我在任一单元格中选择一个段 那么如果我滚动 某些段值就会发生更改 我不知道如何解决这个问题 请指导我 细胞尺寸 160px 段色调颜色 蓝色 Coding
  • 动态更新 UIAlertView 消息和换行符问题

    我需要在 UIAlertView 的消息中显示多行文本 我尝试过添加 n 但没有效果 它仍然显示 这是一个示例 但是 如果我将 iPhone 切换为横向模式 它会按照我的预期显示该消息 然后 如果我切换回纵向模式 它也会正确显示 更新 经过
  • RestKit:如何删除核心数据条目以保持内容与服务器同步?

    我正在使用 RestKit RKObjectManager 从我的服务器获取数据并将其存储在核心数据中 请参阅我的其他post https stackoverflow com questions 17066214 restkit how t
  • 滚动高图图表

    这是我的问题 我正在使用phonegap框架来开发一个混合应用程序 并且我需要这个应用程序具有我决定使用highcharts库的图表 问题是 我似乎无法在触摸图表后滚动 至少在触摸图像的选定部分内部时 我想要做的是防止图表发生任何事件 并显
  • Alamofire 仅在 GET 请求上出现请求错误

    我正在努力将我的项目从 AFNetworking 转移到 Alamofire 真的很喜欢这个项目 POST 请求工作得很好 但是 我在尝试发出 GET 请求时收到此错误 这是一些示例代码 class func listCloudCrednt
  • 找不到 -lDoubleConversion 的库

    我尝试在 XCode 上构建 但是ld library not found for lDoubleConversion发生错误 我可以建造react native run ios 这可行 但 XCode 无法构建 ld 警告 找不到选项 L
  • Angular/ HTML5 到 iOS WKWebView 通信

    我们正在尝试看看发送信号的最佳选择是什么To iOS WKWebView fromAngular 6 HTML5 项目 任何示例都会很棒 我们想要做的是 我们在 Angular 网页上有一个按钮 单击该按钮应该通知 iOS 执行某些操作 我
  • 如何更改某些功能以兼容 iOS 10 或更低版本的 Snapchat 中的某些功能,例如相机视图控制器

    我正在制作一个视图控制器来制作像 snapchat 相机一样的相机视图控制器 我下面的代码在 iOS 11 或更高版本上完美运行 老实说 我并没有真正掌握我的代码 因为我只是按照这个像相机视图控制器这样的 snapchat 的教程进行操作
  • NSNotification 与dispatch_get_main_queue

    和 关联这个问题 https stackoverflow com questions 7905192 iphone grand central dispatch main thread我想知道关于何时使用 NSNotification 在主
  • TypeError:cli.init 不是 React Native 的函数

    在 MacBook Air M1 芯片中运行 npx react native init appName 时 TypeError cli init is not a function at run opt homebrew lib node
  • 核心数据在没有明显原因的情况下恢复到之前的状态

    基于 Core Data 的 iOS 应用程序的一些客户报告称 他们偶尔会丢失数据 这些报告非常奇怪 这就是我想询问您对此的看法的原因 客户报告说 当他们在一段时间 几分钟 几小时或第二天 后重新打开应用程序时 他们的一些数据会丢失就像底层
  • 如何在 Safari 和 Native App 之间共享上下文?

    我有需要通过 Safari 设置一些上下文 上下文标记 然后从本机 iOS 应用程序读取该上下文 这样做的最佳实践是什么 到目前为止的一些想法 在 HTML 5 数据库中设置上下文 但我不确定这是否有效 因为该数据库可能只能从 Safari

随机推荐