Jon*_*nah 8 iphone caching uitableview
我有一个带有大图像的桌面视图,可以填充单元格,并根据图像大小设置行高.不幸的是,当滚动到下一个单元格时,表格严重抖动.
有人告诉我,如果在将行高度和图像加载到表格之前缓存行高度,我的tableview将滚动得更顺畅.我的所有数据都存储在plist中.
我如何去缓存一些东西?代码是什么样的,它在哪里?
谢谢!
这是我加载图像的代码:
- (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;
}
Run Code Online (Sandbox Code Playgroud)
我也使用以下方法计算行高:
- (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;
}
Run Code Online (Sandbox Code Playgroud)
编辑:这是下面的最终代码.
#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;
}
Run Code Online (Sandbox Code Playgroud)
Rob*_*ier 16
缓存不是tableview性能的灵丹妙药.缓存只有在计算成本很高的情况下才有价值,您可以避免计算它.另一方面,如果您在UITableViewCell中只有太多的视图,那么缓存对您无效.如果您的行高度都相同,则无需缓存.如果您使用+[UIImage imageNamed:]
,则系统已经为您缓存了图像.
UITableViewCells最常见的一阶问题是在其中放置太多子视图.你是如何构建你的细胞的?您是否花时间研究表视图编程指南,特别是仔细查看表视图单元?理解本文档将为您节省更多的悲伤.
编辑:(基于上面的代码)
首先,你正在获取一个可重复使用的单元格,然后立即扔掉它,读取一个NIB并迭代所有顶层对象寻找一个单元格(一个看起来几乎就像你刚扔掉的那个单元格).然后你计算出一个字符串,用于打开文件并读取内容.每次UITableView想要一个新的单元格时都会这样做.你会一遍又一遍地为同一行做这件事.
然后,当UITableView想要知道高度时,再次从磁盘读取图像.并且每次UITableView请求时都会这样做(并且它可能会多次询问同一行,但它会尝试对此进行优化).
您应该首先阅读上面链接的UITableView编程指南.希望能帮助很多.当你这样做时,你应该考虑以下事项:
您表示此单元格中只有一个图像视图.你真的需要一个NIB吗?如果您坚持使用NIB(并且在某些情况下有理由使用它们),请阅读编程指南,了解如何实现基于NIB的单元.您应该使用IBOutlet
,而不是尝试迭代顶级对象.
+[UIImage imageNamed:]
将自动查找Resources目录中的文件,而无需计算bundle的路径.它还会自动为您缓存这些图像.
重点-dequeueReusableCellWithIdentifier:
是获取UITableView不再使用的单元格,并且您可以重新配置而不是创建新单元格.你在叫它,但是你马上把它丢掉了.您应该检查它是否返回nil,并且只在NIB中加载它.否则,您只需要更改图像.再次阅读编程指南; 它有很多这方面的例子.只要确保你真的想要了解-dequeueReusableCellWithIdentifier:
正在做什么,并且不要将它视为你在程序中此时输入的内容.
如果你确实需要缓存高度,我做了类似的事情(显示"文章"对象的单元格的缓存高度 - 文章可能是几个子类中的一个):
+ (CGFloat) heightForArticle: (Article*) article atWidth: (CGFloat) width {
static NSCache* heightCache = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
heightCache = [NSCache new];
});
NSAssert(heightCache, @"Height cache must exist");
NSString* key = @"unique"; //Create a unique key here
NSNumber* cachedValue = [heightCache objectForKey: key];
if( cachedValue )
return [cachedValue floatValue];
else {
CGFloat height = 40;//Perform presumably large height calculation here
[heightCache setObject: [NSNumber numberWithFloat: height] forKey: key];
return height;
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7872 次 |
最近记录: |