问题描述
不久,我有一个 NSDictionary
,其中包含我需要在 UITableView
中显示的图像的 url.每个单元格都有一个标题和一个图像.我成功地做到了这一点,尽管滚动滞后,因为似乎细胞每次进入屏幕时都会下载它们的图像.搜索了一下,在github上找到了SDWebImage
.这使得滚动滞后消失了.我不完全确定它做了什么,但我相信它做了一些缓存.但!每次我第一次打开应用程序时,我都看不到图像,我必须向下滚动并备份才能到达.如果我用主页按钮退出应用程序,然后再次打开,那么缓存似乎正在工作,因为屏幕上的图像是可见的,但是,如果我向下滚动一个单元格,则下一个单元格没有图像.直到我滚动过去并备份,或者如果我点击它.这是缓存应该如何工作吗?或者缓存从网络下载的图像的最佳方法是什么?这些图像很少更新,所以我几乎只是将它们导入到项目中,但我喜欢有可能在不上传更新的情况下更新图像..
Shortly, I have an NSDictionary
with urls for images that I need to show in my UITableView
. Each cell has a title and an image. I had successfully made this happen, although the scrolling was lagging, as it seemed like the cells downloaded their image every time they came into the screen.I searched for a bit, and found SDWebImage
on github. This made the scroll-lagg go away. I am not completely sure what it did, but I believed it did some caching.But! Every time I open the app for the first time, I see NO images, and I have to scroll down, and back up for them to arrive. And if I exit the app with home-button, and open again, then it seemes like the caching is working, because the images on the screen are visible, however, if I scroll one cell down, then the next cell has no image. Until i scroll past it and back up, or if I click on it. Is this how caching is supposed to work? Or what is the best way to cache images downloaded from the web? The images are being updated rarily, so I was close to just import them to the project, but I like to have the possibility to update images without uploading an update..
是否不可能在启动时从缓存中加载整个 tableview 的所有图像(假设缓存中有东西)?这就是为什么我有时会看到没有图像的单元格?
Is it impossible to load all the images for the whole tableview form the cache(given that there is something in the cache) at launch? Is that why I sometimes see cells without images?
是的,我很难理解缓存是什么.
And yes, I'm having a hard time understanding what cache is.
--编辑--
我仅使用相同大小 (500x150) 的图像尝试了此操作,并且方面错误消失了,但是当我向上或向下滚动时,所有单元格上都有图像,但起初它们是错误的.单元格在视图中显示几毫秒后,将显示正确的图像.这非常令人讨厌,但也许它必须是这样?.. 似乎它首先从缓存中选择了错误的索引.如果我滚动缓慢,那么我可以看到图像从错误的图像闪烁到正确的图像.如果我快速滚动,那么我相信错误的图像始终可见,但由于快速滚动,我无法分辨.当快速滚动变慢并最终停止时,错误的图像仍然出现,但在停止滚动后立即更新为正确的图像.我也有一个自定义的 UITableViewCell
类,但我没有做任何大的改变..我还没有仔细研究我的代码,但我想不出可能有什么问题.. 也许我的顺序有误.. 我用 java、c#、php 等编写了很多程序,但我很难理解 Objective-c,以及所有的 .h
和 .m ...我也有`
I tried this with only images of the same size (500x150), and the aspect-error is gone, however when I scroll up or down, there are images on all cells, but at first they are wrong. After the cell has been in the view for some milliseconds, the right image appears. This is amazingly annoying, but maybe how it has to be?.. It seemes like it chooses the wrong index from the cache at first. If I scroll slow, then I can see the images blink from wrong image to the correct one. If I scroll fast, then I believe the wrong images are visible at all times, but I can't tell due to the fast scrolling. When the fast scrolling slows down and eventually stops, the wrong images still appear, but immediately after it stops scrolling, it updates to the right images. I also have a custom UITableViewCell
class, but I haven't made any big changes.. I haven't gone through my code very much yet, but I can't think of what may be wrong.. Maybe I have something in the wrong order.. I have programmed much in java, c#, php etc, but I'm having a hard time understanding Objective-c, with all the .h
and .m
...I have also `
@interface FirstViewController : UITableViewController{
/**/
NSCache *_imageCache;
}
(以及其他变量)在 FirstViewController.h
中.这不正确吗?
(among other variables) in FirstViewController.h
. Is this not correct?
这是我的 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;
}
推荐答案
缓存只是意味着保留您需要的数据的副本,这样您就不必从某些较慢的源加载它.例如,微处理器通常有高速缓存,用于保存数据副本,这样它们就不必访问速度较慢的 RAM.硬盘通常具有内存缓存,文件系统可以从中更快地访问最近访问过的数据块.
Caching just means keeping a copy of the data that you need so that you don't have to load it from some slower source. For example, microprocessors often have cache memory where they keep copies of data so that they don't have to access RAM, which is a lot slower. Hard disks often have memory caches from which the file system can get much quicker access to blocks of data that have been accessed recently.
同样,如果您的应用从网络加载了大量图片,您可能需要将它们缓存在您的设备上,而不是每次需要时都下载它们.有很多方法可以做到这一点 - 听起来您已经找到了一种方法.您可能希望将下载的图像存储在应用程序的/Library/Caches 目录中,尤其是在您不希望它们发生更改的情况下.从辅助存储加载图像比通过网络加载要快得多.
Similarly, if your app loads a lot of images from the network, it may be in your interest to cache them on your device instead of downloading them every time you need them. There are lots of ways to do that -- it sounds like you already found one. You might want to store the images you download in your app's /Library/Caches directory, especially if you don't expect them to change. Loading the images from secondary storage will be much, much quicker than loading them over the network.
您可能还对鲜为人知的NSCache 类,用于将您需要的图像保存在内存中.NSCache 像字典一样工作,但是当内存紧张时它会开始释放它的一些内容.您可以先检查给定图像的缓存,如果在那里找不到它,则可以查看缓存目录,如果在那里找不到,则可以下载它.这些都不会在您第一次运行应用时加快图像加载速度,但是一旦您的应用下载了大部分所需的内容,它的响应速度就会更快.
You might also be interested in the little-known NSCache class for keeping the images you need in memory. NSCache works like a dictionary, but when memory gets tight it'll start releasing some of its contents. You can check the cache for a given image first, and if you don't find it there you can then look in your caches directory, and if you don't find it there you can download it. None of this will speed up image loading on your app the first time you run it, but once your app has downloaded most of what it needs it'll be much more responsive.
这篇关于在 ios 应用程序上缓存图像的最佳方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!