在NSTableView中加载图像时出现奇怪的行为

时间:2013-09-09 11:51:22

标签: objective-c macos cocoa nstableview nstablecellview

我正在用GCD加载图片,我有一些奇怪的行为。

滚动表格视图时,每张专辑都会开始提取图稿。 NSTableCellView快速显示许多错误的艺术品,直到可能一秒之后它最终显示正确的一个然后停止。

显然这意味着,在调度之后,NSTableCellView的变量不再指向同一个实例,这会导致一遍又一遍地改变同一个单元的图像。

我尝试通过在调度块中调用viewAtColumn:row:indexOfObject:来解决此问题,但它无法解决问题。

有什么建议吗?


代码

- (ITAlbumTableCellView *)makeTableCellViewWithAlbum:(ITLibAlbum *)album {
    ITAlbumTableCellView *cellView = (ITAlbumTableCellView *)[self makeTableCellViewWithIdentifier:kTCVIAlbum];

    // ... Mapping Stuff

    // Set artwork
    if (![self._imageCache objectForKey:album]) {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSImage *artwork = album.artwork;
            if (!artwork || !artwork.isValid) artwork = [NSImage imageNamed:@"noArtwork"];

            [self._imageCache setObject:artwork forKey:album];

            dispatch_async(dispatch_get_main_queue(), ^{
                NSTableCellView *tcv = [self.tableView viewAtColumn:0 row:[self.tableContent indexOfObject:album] makeIfNecessary:NO];
                tcv.imageView.image = artwork;
            });
        });
    } else {
        cellView.imageView.image = [self._imageCache objectForKey:album];
    }

    return cellView;
}

1 个答案:

答案 0 :(得分:1)

您使用可重复使用的单元格,因此当单元格隐藏在边界之外时,它会重复使用以显示另一个数据。快速修复:

 - (ITAlbumTableCellView *)makeTableCellViewWithAlbum:(ITLibAlbum *)album {
ITAlbumTableCellView *cellView = (ITAlbumTableCellView *)[self makeTableCellViewWithIdentifier:kTCVIAlbum];
static int tag = 0;
tag++;
int tagForBlock = tag;
cellView.tag = tag;
if (![self._imageCache objectForKey:album]) {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSImage *artwork = album.artwork;
        if (!artwork || !artwork.isValid) artwork = [NSImage imageNamed:@"noArtwork"];

        [self._imageCache setObject:artwork forKey:album];

        dispatch_async(dispatch_get_main_queue(), ^{
            if(tagForBlock != cellView.tag)
                return;
            NSTableCellView *tcv = [self.tableView viewAtColumn:0 row:[self.tableContent indexOfObject:album] makeIfNecessary:NO];
            tcv.imageView.image = artwork;
        });
    });
} else {
    cellView.imageView.image = [self._imageCache objectForKey:album];
}

return cellView;
}