繁体   English   中英

iPhone自定义绘制UITableViewCell,如何在线程中加载+从网络插入图像?

[英]iPhone custom drawn UITableViewCell , how to load + insert images from the web in a thread?

我一直在绘制自定义表格单元格(使用来自苹果的样本作为基础),现在必须做一个显示来自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个图像在表格中重复(尽管其他文本更新)。

我现在并不担心缓存,但是有没有关于如何做到这一点的样本,或者有人能指出我正确的方向吗? 谢谢。

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

cellForRowAtIndexPath: ,您应该从缓存(myProduct对象,NSArray,无论如何)获取图像。 如果它不在那里,你应该检查一个标志,看它是否已被加载。 如果尚未加载,则设置该标志并分离新线程(您应该查看NSOperation ,它将排队工作并保护您不会立即启动太多线程)。

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

我希望这是一个有用的概述。

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

这应该回答您的问题。 LazyTableImages

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

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

return cell;

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM