如何为tableview缓存一些东西? [英] How do I cache something for a tableview?

查看:78
本文介绍了如何为tableview缓存一些东西?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含大图像的桌面视图,这些图像填​​充单元格,并根据图像大小设置行高。不幸的是,当滚动到下一个单元格时,表格突然出现。

I have a tableview with large images that fill the cells and the row heights are set based on the image size. Unfortunately, the table jerks badly when scrolling to the next cell.

我被告知如果我先缓存行高和图像,我的tableview会滚动得更顺畅他们被加载到表中。
我的所有数据都存储在plist中。

I've been told that my tableview will scroll more smoothly if I cache the row heights and the images before they are loaded into the table. All my data are stored in a plist.

我如何进行缓存?
代码是什么样的,它在哪里?

How do I go about caching something? What does the code look like and where does it go?

谢谢!

这是我的用于加载图像的代码:

Here's my code for loading the images:

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

    static NSString *detailTableViewCellIdentifier = @"Cell";

    DetailTableViewCell *cell = (DetailTableViewCell *) 
        [tableView dequeueReusableCellWithIdentifier:detailTableViewCellIdentifier];

    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"DetailTableViewCell" owner:self options:nil];
    for(id currentObject in nib)
    {
        cell = (DetailTableViewCell *)currentObject;
    }
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSString *Path = [[NSBundle mainBundle] bundlePath];
    NSString *MainImagePath = [Path stringByAppendingPathComponent:([[appDelegate.sectionsDelegateDict objectAtIndex:indexPath.section] objectForKey:@"MainImage"])];

    cell.mainImage.image = [UIImage imageWithContentsOfFile:MainImagePath];

    return cell;
}

我还使用以下方法计算行高:

I'm also using the following for calculating the row height:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    AppDelegate *appDelegate = (DrillDownAppAppDelegate *)[[UIApplication sharedApplication] delegate];
    NSString *Path = [[NSBundle mainBundle] bundlePath];
    NSString *MainImagePath = [Path stringByAppendingPathComponent:([[appDelegate.sectionsDelegateDict objectAtIndex:indexPath.section] objectForKey:@"MainImage"])];
    UIImage *imageForHeight = [UIImage  imageWithContentsOfFile:MainImagePath]; 
    imageHeight = CGImageGetHeight(imageForHeight.CGImage);  
    return imageHeight;
}

编辑:以下是最终代码。

Here is the final code below.

#define PHOTO_TAG 1
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 static NSString *CellIdentifier = @"Photo";

 UIImageView *photo;
 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

 AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
 UIImage *theImage = [UIImage imageNamed:[[appDelegate.sectionsDelegateDict objectAtIndex:indexPath.section] objectForKey:@"MainImage"]];

 imageHeight = CGImageGetHeight(theImage.CGImage);
 imageWidth = CGImageGetWidth(theImage.CGImage);

if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    photo = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, imageWidth, imageHeight)] autorelease];
    photo.tag = PHOTO_TAG;
    [cell addSubview:photo];
   } else {
    photo = (UIImageView *) [cell viewWithTag:PHOTO_TAG];
    [photo setFrame:CGRectMake(0, 0, imageWidth, imageHeight)];
   }

 photo.image = theImage;
 return cell;
 }


推荐答案

缓存不是万能的灵丹妙药tableview表现。缓存只有在计算成本很高的情况下才有价值,您可以避免计算它。另一方面,如果您在UITableViewCell中只有太多的视图,那么缓存对您无效。如果您的行高度都相同,则无需缓存。如果您使用 + [UIImage imageNamed:] ,那么系统已经为您缓存了图像。

Caching is not a panacea for tableview performance. Caching is only valuable if there is something expensive to calculate, and you can avoid calculating it. If, on the other hand, you simply have too many views in your UITableViewCell, then caching will do nothing for you. If your row heights are all the same, then there's nothing to cache. If you use +[UIImage imageNamed:], then the system is already caching your images for you.

UITableViewCells最常见的一阶问题是在其中放置太多子视图。你是如何构建你的细胞的?你有没有花时间研究Table View编程指南,特别是仔细查看表视图单元格?理解这份文件将为您节省更多的悲伤。

The most common first-order problem with UITableViewCells is putting too many subviews in them. How have you constructed your cell? Have you spent time studying the Table View Programming Guide, particularly A Closer Look at Table-View Cells? Understanding this document will save you much grief later.

(基于上面的代码)

首先,你正在取一个可重复使用的单元格,然后立即扔掉它,读取一个NIB并迭代所有顶层对象寻找一个单元格(一个看起来几乎就像你扔掉的那个单元格)。然后你计算出一个字符串,用于打开文件并读取内容。每次UITableView想要一个新的单元格时都会这样做。你会一遍又一遍地为同一行做这件事。

First, you're fetching a reusable cell, and then immediately throwing it away, reading a NIB and iterating over all the top level objects looking for a cell (one that looks almost exactly like the one you just threw away). Then you work out a string, which you use to open a file and read the contents. You do this every time UITableView wants a new cell, which is a lot. And you do it over and over again for the same rows.

然后,当UITableView想要知道高度时,你再次从磁盘读取图像。并且每次UITableView请求时都会这样做(并且它可能会多次询问同一行,但它会尝试对此进行优化)。

Then, when UITableView wants to know the height, you read the image off of disk again. And you do that every time UITableView asks (and it may ask many times for the same row, though it does try to optimize this).

您应该首先阅读UITableView编程指南我在上面链接。希望能帮助很多。当你这样做时,你应该考虑以下事项:

You should start by reading the UITableView Programming Guide I link above. That's hopefully going to help a lot. When you've done that, here are the things you should be thinking about:


  • 你表示只有一个此单元格中的单个图像视图。你真的需要一个NIB吗?如果您坚持使用NIB(并且在某些情况下有理由使用它们),请阅读编程指南,了解如何实现基于NIB的单元。您应该使用 IBOutlet ,而不是尝试迭代顶级对象。

  • You indicated that there is nothing but a single image view in this cell. Do you really need a NIB for that? If you do stick with a NIB (and there are reasons to use them in some case), then read the Programming Guide about how to implement a NIB-base cell. You should be using IBOutlet, not trying to iterate over the top-level objects.

+ [UIImage imageNamed:] 将自动查找Resources目录中的文件,而无需计算bundle的路径。它还会自动缓存这些图像。

+[UIImage imageNamed:] will automatically find files in your Resources directory without you having to work out the bundle's path. It will also cache those images for you automatically.

-dequeueReusableCellWithIdentifier:是获取UITableView不再使用的单元格,您可以重新配置而不是重新配置。你在叫它,但是你马上把它丢掉了。您应该检查它是否返回nil,并且只在NIB中加载它。否则,您只需要更改图像。再次阅读编程指南;它有很多这方面的例子。只要确保你真的想要了解 -dequeueReusableCellWithIdentifier:正在做什么,并且不要将它视为你在程序中此时输入的内容。

The point of -dequeueReusableCellWithIdentifier: is to fetch a cell that UITableView is no longer using and that you can reconfigure rather than you making a new one. You're calling it, but you immediately throw it away. You should check if it returned nil, and only load it out of the NIB if it did. Otherwise, you just need to change the image. Again, read the Programming Guide; it has many, many examples of this. Just make sure that you really try to understand what -dequeueReusableCellWithIdentifier: is doing, and don't treat it as just something you type at this point in the program.

这篇关于如何为tableview缓存一些东西?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆