ios - 调度队列上的 TableView 单元格中填充了错误的数据

标签 ios uitableview grand-central-dispatch

我有一个 iOS 应用程序,它有一个 UITableView 和包含 UIImageView 的自定义 TableViewCells。该图像是从 Web 服务加载的,因此在初始加载期间,我会显示“正在加载”图像,然后使用 gcd 进行分派(dispatch)并获取与该单元格数据匹配的图像。

当我使用 DISPATCH_QUEUE_PRIORITY_HIGH 全局队列执行图像提取时,我偶尔会在 tableview 单元格中加载错误的图像。如果我使用自己的自定义队列,则会将正确的图像填充到单元格中,但表格 View 的性能很糟糕。

这是代码...

    // See if the icon is in the cache
if([self.photoCache objectForKey:[sample valueForKey:@"api_id"]]){
    [[cell sampleIcon]setImage:[self.photoCache objectForKey:[sample valueForKey:@"api_id"]]];
}
else {
    NSLog(@"Cache miss");
        [cell.sampleIcon setImage:nil];
        dispatch_queue_t cacheMissQueue = dispatch_queue_create("cacheMissQueue", NULL);
        //dispatch_queue_t cacheMissQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
        dispatch_async(cacheMissQueue, ^{
            if(sample.thumbnailFilename && sample.api_id){
                NSData *thumbNailData = [[NSData alloc] initWithContentsOfFile:sample.thumbnailFilename];
                UIImage *thumbNailImage = [[UIImage alloc]initWithData:thumbNailData];
                if(thumbNailImage){
                    // Set the cell
                    dispatch_sync(dispatch_get_main_queue(), ^{
                        [[cell sampleIcon]setImage:thumbNailImage];
                        [cell setNeedsLayout];
                    });
                    // save it to cache for future references
                    NSLog(@"DEBUG: Saving to cache %@ for sample %@",sample.thumbnailFilename,[sample objectID]);
                    [self.photoCache setObject:thumbNailImage forKey:sample.api_id];
                }
            }
        });
        dispatch_release(cacheMissQueue);
}

最佳答案

观看 WWDC 2012 session #211 帮助很大,我将代码从使用 GCD 更改为 NSOperationQueue,它解决了问题。

新代码...

[[self imgQueue]addOperationWithBlock:^{
            if(sample.thumbnailFilename && sample.api_id){
                NSData *thumbNailData = [[NSData alloc] initWithContentsOfFile:sample.thumbnailFilename];
                UIImage *thumbNailImage = [[UIImage alloc]initWithData:thumbNailData];
                if(thumbNailImage){
                    // Set the cell
                    [[NSOperationQueue mainQueue]addOperationWithBlock:^{
                        [[cell sampleIcon]setImage:thumbNailImage];
                        [cell setNeedsLayout];
                    }];
                    // save it to cache for future references
                    [self.photoCache setObject:thumbNailImage forKey:sample.api_id];
                }
            }

        }];

关于ios - 调度队列上的 TableView 单元格中填充了错误的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11800846/

相关文章:

iphone - Objective-C,使用 UI 事件取消调度队列

ios - 从另一个类向当前 View Controller 添加 View

java - 在 Java 和 iOS 中的位置

swift - 从一个 ViewController 转到另一个 ViewController 并更新

ios - 仅当我按几秒钟时,Swift UITableView 才会调用 didSelectRowAt

ios - 按顺序异步下载图片

ios - iOS/Swift 项目中自定义统一类型标识符 (UTI) 的图标未显示

ios - 如何修复 Twilio 可编程语音错误 - 52134 无效的 APNs 设备 token

ios - UITableViewCell 类中的 PerfomSegue

ios - Swift 中的 dispatch_once 单例