0

我正在将图像异步加载到 UITableView 中的单元格上。代码如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

// after getting the cell..

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSString *imageUrl = [someMethodToGetImageUrl];
        NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL imageUrl]];
        dispatch_async(dispatch_get_main_queue(), ^{
            cell.imageView.image = [UIImage imageWithData:imageData];
            [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
        });
    });

}

我的问题是,如果这个 tableView 在触发调度之后被释放(例如从 navigationController 堆栈中弹出),但在线程完成尝试设置单元格的图像之前,会发生什么。该单元也将被释放,并且尝试对该单元执行操作会导致崩溃,不是吗?

我一直在使用上面的代码崩溃。如果我进入这个 tableView 然后立即退出,我会在线崩溃:

[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];

如果我将其更改为:

[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];

崩溃消失了,这对我来说真的没有意义。有人可以向我解释为什么会这样吗?谢谢。

4

1 回答 1

2

任何可能使块超出其原始范围的例程都需要复制它。 dispatch_async()做。

当一个块被复制时,它会保留它引用的任何对象指针变量。如果块以实例变量的形式隐式访问self,它会保留self. 它持有这些引用,直到它自己被释放。

在您的示例中,cellimageDataindexPathtableView都保留到块完成。

于 2012-04-18T23:07:56.273 回答