1

我一直在绘制自定义表格单元格(使用来自苹果的样本作为基础),现在不得不做一个显示来自 URL 的图像的单元格 - 每个单元格都会有不同的图像(基于它拥有的一些数据) 但所有单元格都是相同的,因此相同的重用 ID。

这样做的正确结构是什么?显然我需要在新线程中加载图像。到目前为止,我在自己的线程中运行的单元格视图类中有以下函数:


- (void)loadImage
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    self.img = [UIImage imageWithData: [NSData dataWithContentsOfURL: [NSURL URLWithString: [myProduct objectForKey:@"ImagePath"]]]];
    [self setNeedsDisplay];
    [pool release];
}

当我从 drawRect 函数本身(这很糟糕)调用它时,它“工作”,但显然每次发生任何事情时都会调用它(选择等)。如果我把它放在单元格 uiview 的 init 函数中,那么它只会被前 8 个单元格调用,然后它们会被重用。其他变体最终使图像在重复使用单元格时不会“重置”,因此相同的 8 张图像在表格中重复出现(尽管其他文本更新)。

我暂时不担心缓存,但是有没有关于如何做到这一点的示例,或者有人能指出我正确的方向吗?谢谢。

4

5 回答 5

2

解决方案必须更加复杂,因为默认情况下 UITableView 回收单元格(当一个滚动离开顶部时,它会移动到底部并重新配置新数据)。因此,您可能开始下载图像,但在下载完成之前单元格的内容已更改。

cellForRowAtIndexPath:中,您应该从缓存(您的 myProduct 对象、NSArray 等)中获取图像。如果它不存在,您应该检查一个标志以查看它是否已经被加载。如果尚未加载,则设置该标志并分离一个新线程(您应该查看NSOperation,它会将工作排队并防止您一次启动太多线程)。

在您的线程中,您应该下载图像,然后使用图像performSelectorOnMainThread:target:waitUntilDone:调用主线程上的方法。该方法可以更新缓存,将 isLoading 标志设置为 NO,然后更新单元格。这样做很重要,因为 Cocoa 要求所有 UI 更新代码都在主线程上。

我希望这是一个有用的大纲。

于 2009-11-15T17:56:33.137 回答
1

如果您没有看到 Apple 的明确文档表明 UIImage 是线程安全的,我认为您不应该这样做。而是将您的图像作为 NSData 并将其转换为 UIImage 在您的主线程中。基本规则是所有 UIKit 工作必须在你的主线程中完成,否则行为是未定义的。

于 2009-11-15T23:01:35.557 回答
1

这应该回答您的查询。懒表图像

于 2010-07-16T04:55:21.093 回答
0

看看斯坦福讲座 cs193p 中的适当幻灯片/视频/代码示例 ... iphone 应用程序编程...

于 2009-11-15T22:04:25.917 回答
0

好吧,当您使单元格出列时,您可以强制在那里加载图像。您不必在 init 中执行此操作...通常您会这样做:

cell = dequeueCell...
if (!cell) {
   //create one
}

return cell;

您可以做的是在返回单元格之前,如果它是您想要的单元格类型,您可以强制加载图像。这样,无论何时显示,您都可以从缓存中获取它(如果存在),如果不存在,请访问网络获取它。

于 2009-11-15T17:44:08.423 回答