Objective c 如何验证从队列返回的内容是否与预期的UITableView单元格匹配?

Objective c 如何验证从队列返回的内容是否与预期的UITableView单元格匹配?,objective-c,ios,uitableview,cs193p,Objective C,Ios,Uitableview,Cs193p,我是iOS开发新手,这是我关于stackoverflow的第一个问题,尽管我经常来这里。谢谢你这么好的资源 我正在参加斯坦福CS193P课程,但在“作业5额外学分1”方面遇到了问题。 我有一个显示标题、副标题和缩略图的UITableView。我将缩略图提取排队,但需要在缩略图图像返回时验证表单元格是否未被回收 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)i

我是iOS开发新手,这是我关于stackoverflow的第一个问题,尽管我经常来这里。谢谢你这么好的资源

我正在参加斯坦福CS193P课程,但在“作业5额外学分1”方面遇到了问题。
我有一个显示标题、副标题和缩略图的UITableView。我将缩略图提取排队,但需要在缩略图图像返回时验证表单元格是否未被回收

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Photo";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    NSDictionary *imageDescription = [self.photoList objectAtIndex:indexPath.row];
    NSString *expectedPhotoID = [imageDescription objectForKey:FLICKR_PHOTO_ID];

    // Configure the cell...

    cell.imageView.image = [UIImage imageNamed:@"placeholder.png"];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        UIImage *imageThumb = [self imageForCell:imageDescription];
        [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]]; // simulate 2 sec latency

        dispatch_async(dispatch_get_main_queue(), ^{
            NSString *photoID = [imageDescription objectForKey:FLICKR_PHOTO_ID];
            if ([expectedPhotoID isEqualToString:photoID]) {
                cell.imageView.image = imageThumb;
            } else {
                NSLog(@"cellForRowAtIndexPath: Got image for recycled cell");
            }
        });
    });

  return cell;
}
在此代码中,
photoID
始终匹配
expectedPhotoID
。我假设这是因为
imageDescription
指针在创建队列时用于这两个队列。我尝试过直接使用
[self.photoList objectAtIndex:indexath.row]
(代替
imageDescription
),但也没有成功。似乎在创建队列时也解决了此问题


我在这里缺少一些基本的理解,非常感谢您的帮助。

表视图并不是为所有行分配表视图单元格。相反,只为可见行(或更多行)分配单元格。如果滚动表格,一些行消失,另一些行出现。对于新出现的行,表视图尝试重用不再需要的单元格。(这就是
dequeueReusableCellWithIdentifier:
所做的。)

如果启动异步任务以检索单元格的图像,则可能会发生以下情况:

当任务完成并执行最里面的块时,单元格同时被重新用于另一行!在这种情况下,将图像指定给单元格是没有意义的

因此,当您有图像时,您必须检查单元格是否仍处于与以前相同的位置。例如,您可以调用
[tableView indexPathForCell:cell]
并将该值与原始的
indexPath
进行比较。如果它们相同,则单元格仍处于相同位置,您可以指定图像。如果没有,则必须放弃该图像

但这只是最简单的解决方案。更好的解决方案是缓存所有行的图像


我只能推荐WWDC 2012年会议2011“在iOS上构建并发用户界面”。它涵盖了这个主题。

我不知道这里是否遗漏了什么,但您两次都在呼叫
[imageDescription objectForKey:FLICKR\u PHOTO\u ID]
。在什么可能的情况下,这两种情况将不相等?:)添加更多关于您尝试执行的操作的详细信息。Dustin,我粘贴的代码中您是正确的。在我提到的笔记中,我还使用了[self.photoList objectAtIndex:indexath.row]而不是imageDescription。我曾希望indexath:row将在UI线程中派生。显然不是,它似乎是在创建队列时解决的。那么…我如何在主队列线程中放置一些东西来比较调用前的单元格和提取完成后的单元格?Martin,谢谢你的回复。回收的电池是我试图解决的问题。我不明白你的解决方案怎么能在100%的时间里都有效。既然IndexXPath是“在tableView中定位一行的索引路径”,那么我是否有可能得到相同的行但错误的内容?例如,假设图像是针对第5行的。无论我如何滚动,总是会有第5行,我会插入错误的图像。我尝试了Martin的建议,它确实有效。现在,我想更好地理解这一点。首先,tableView似乎对所有行进行唯一编号。注意,如果我的表显示90行,IndexPath将有90行号。我想当然地认为行号会和单元格一起循环使用。看,如果只有10行适合显示,行号将从0-19,而不是0-89。我想确认的另一件事是,这项工作的原因。是否因为主队列中的TableView消息使用的是调用my CellForRowatineXpath时传入的单元格,而不是上次调用的单元格。@Dan如果答案回答了您的问题,请接受它。如果你还有其他问题,问它。