简单来说,我有一个包含图片url的NSDictionary
,需要在我的UITableView
中显示这些图片。每个单元格都有一个标题和一张图片。虽然我成功实现了这一点,但滚动时会出现延迟,因为似乎每次单元格进入屏幕时都会下载它们的图片。
我搜索了一下,在github上找到了SDWebImage
。这使得滚动延迟消失了。我不完全确定它做了什么,但我相信它进行了一些缓存。
但是!每次我第一次打开应用程序时,我看不到任何图片,我必须向下滚动,再向上滚动才能看到它们。如果我按home键退出应用程序,然后再次打开,那么似乎缓存正在工作,因为屏幕上的图像是可见的,但是,如果我向下滚动一个单元格,那么下一个单元格就没有图片。除非我向下滚动并向上滚动,或者点击它。这是缓存应该工作的方式吗?或者从web下载图片的最佳方式是什么?这些图像很少更新,所以我几乎要将它们导入项目中,但我希望有更新图像的可能性而无需上传更新...
在启动时从缓存中加载整个tableview的所有图片是不可能的吗?这就是为什么有时我会看到没有图片的单元格吗?
是的,我很难理解什么是缓存。
--编辑--
我尝试了只使用相同大小的图像(500x150),方面错误消失了,但是当我向上或向下滚动时,所有单元格都有图片,但一开始它们是错误的。在单元格在视图中停留了一些毫秒后,正确的图像出现了。这非常令人恼火,但也许这就是应该的方式?..它似乎在一开始从缓存中选择了错误的索引。如果我滚动得很慢,那么我可以看到图像从错误的图像闪烁到正确的图像。如果我快速滚动,那么我相信错误的图像在任何时候都可见,但由于快速滚动,我无法确定。当快速滚动减慢并最终停止时,错误的图像仍然出现,但在停止滚动后立即更新为正确的图像。我还有一个自定义的UITableViewCell
类,但我没有做出任何重大更改...我还没有仔细查看我的代码,但我想不出可能出错的地方...也许我有些东西放错了顺序..我在java、c#、php等方面编程很多,但我很难理解Objective-c,因为它涉及到 .h
和.m
...我还有...
@interface FirstViewController : UITableViewController{
/**/
NSCache *_imageCache;
}
在FirstViewController.h
中,包括其他变量。这不正确吗?
这是我的cellForRowAtIndexPath
。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"hallo";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSMutableArray *marr = [hallo objectAtIndex:indexPath.section];
NSDictionary *dict = [marr objectAtIndex:indexPath.row];
NSString* imageName = [dict objectForKey:@"Image"];
//NSLog(@"url: %@", imageURL);
UIImage *image = [_imageCache objectForKey:imageName];
if(image)
{
cell.imageView.image = image;
}
else
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString* imageURLString = [NSString stringWithFormat:@"example.com/%@", imageName];
NSURL *imageURL = [NSURL URLWithString:imageURLString];
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:imageURL]];
if(image)
{
dispatch_async(dispatch_get_main_queue(), ^{
CustomCell *cell =(CustomCell*)[self.tableView cellForRowAtIndexPath:indexPath];
if(cell)
{
cell.imageView.image = image;
}
});
[_imageCache setObject:image forKey:imageName];
}
});
}
cell.textLabel.text = [dict objectForKey:@"Name"];
return cell;
}
cellRowRowAtIndexPath
中发布你的代码以及其他相关内容吗?缓存只是将你希望再次访问的东西存储在更容易到达的地方,以加快后续访问速度。在这种情况下,缓存意味着你的应用程序应该在第一次下载图像数据后实际存储每个单元格的图像数据,然后在任何需要显示特定单元格的时候重复使用它(这就是 SDWebImage 应该为你完成的工作)。 - Dimadispatch_async
之前初始化cell.imageView.image
。 - Rob