Ios 向上滚动时,UITableView变慢
解决方案:使用SDWebImage: 我有一个UITableView,在滚动时会变得非常滞后。我发现当我正在使用的图像返回屏幕时会出现延迟 我正在使用自定义UITableViewCell。这也是它落后的原因吗 我的自定义UITableViewCell: 我的代码:Ios 向上滚动时,UITableView变慢,ios,objective-c,uitableview,Ios,Objective C,Uitableview,解决方案:使用SDWebImage: 我有一个UITableView,在滚动时会变得非常滞后。我发现当我正在使用的图像返回屏幕时会出现延迟 我正在使用自定义UITableViewCell。这也是它落后的原因吗 我的自定义UITableViewCell: 我的代码: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d%d",indexPath.row,indexPath.section];
tableViewCellActiviteiten *cell = (tableViewCellActiviteiten *)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"tableViewCellActiviteiten" owner:self options:nil];
cell = (tableViewCellActiviteiten *)[nib objectAtIndex:0];
}
cell.thetitle.text = [self.alletitels objectAtIndex:indexPath.row];
cell.thesubtitle.text = [self.allesubtitels objectAtIndex:indexPath.row];
NSString * imagePath = [self.alleimages objectAtIndex:indexPath.row];
NSURL * imageURL = [NSURL URLWithString:imagePath];
NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage * image = [UIImage imageWithData:imageData];
cell.image.image = image;
return cell;
}
阵列的内容:
self.alletitels
包含一个字符串:“活动标题”
self.allesubitels
包含一个字符串:“活动字幕”
self.allelimages
包含一个url:“
有人能告诉我是什么原因导致了延迟滚动吗?这里有两行:
NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage * image = [UIImage imageWithData:imageData];
是什么显著降低了您的桌面性能
每次刷新单元格时,您都在同步获取和加载图像数据
以某种方式缓存(或本地保存)要显示的图像会更聪明。如果它们没有保存在本地或缓存中,则只需获取这些图像(并在“
cellforrowatinexpath:
”方法之外异步执行该操作)。您正试图在滚动的同一UI线程上加载图像。您应该将它们加载到后台缓存中,然后在它们准备好显示时从缓存中获取 问题在于每次调用tableView:cellforrowatinexpath:
方法时,您的代码都会生成一个图像。每次屏幕上出现单元格时都会调用此方法,因此如果滚动速度非常快,此方法将开始同步分配大量图像,这将减慢滚动速度
作为一个快速解决方案,在视图控制器中实现NSCache并在其中存储图像
UIImage *image = [_imageCache objectForKey:@indexPath.row];
if (image == nil) {
NSString * imagePath = [self.alleimages objectAtIndex:indexPath.row];
NSURL * imageURL = [NSURL URLWithString:imagePath];
NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
image = [UIImage imageWithData:imageData];
[_imageCache setObject:image forKey:@indexPath.row];
}
cell.image.image = image;
_imageCahce是可以实现的视图控制器的实例变量
希望这有帮助,干杯 在创建cell时,您正在进行同步网络调用以下载图像。这些调用会阻止主线程,直到下载用于cell的映像。滞后时间将根据网络质量而变化 解决这个问题的方法是使用称为“延迟加载”的技术。在此技术中,图像加载将在单独的线程上进行,从而解除主线程的阻塞。图像被下载,然后应用到正确的容器
UIImageView
。这里是用于在表视图中延迟加载图像的
您也可以使用。这也将为您进行图像缓存
#import <SDWebImage/UIImageView+WebCache.h>
...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
// Here we use the new provided setImageWithURL: method to load the web image
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
return cell;
}
#导入
...
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
静态NSString*MyIdentifier=@“MyIdentifier”;
UITableViewCell*单元格=[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
如果(单元格==nil)
{
单元格=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier]自动释放];
}
//这里我们使用新提供的setImageWithURL:方法来加载web图像
[cell.imageView setImageWithURL:[NSURL URLWithString:@]http://www.domain.com/path/to/image.jpg"]
占位符图像:[UIImage ImageName:@“placeholder.png”];
返回单元;
}
希望有帮助 我有一个类似的问题,我用Profiler检查了它,所以这里有几个问题: 1) 如果您使用了错误的可重用标识符,则应始终使用相同的标识符 与此相反:
NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d%d",indexPath.row,indexPath.section];
使用以下命令:
NSString *CellIdentifier = @"MyIdentifier";
欲了解更多信息,请阅读:
2) loadNibNamed方法非常慢(加上您每次都为每个单元格加载它),您应该去掉nib,并通过覆盖UITableViewCell的此方法从代码中放置UI元素
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier;
3) 使用你正在为你在应用程序中获得的每个图像进行同步网络调用。尝试
它将从web异步下载您的图像。您将能够消除应用程序中的延迟。:-)随着缓存的增加,你也可以考虑使用Grand Central Debug在后台加载图片。加载单元格时,放入UIActivityIndicator,然后在单独的线程中用图像替换它
// get a data provider referencing the relevant file
CGDataProviderRef dataProvider = CGDataProviderCreateWithFilename(filename);
// use the data provider to get a CGImage; release the data provider
CGImageRef image = CGImageCreateWithPNGDataProvider(dataProvider, NULL, NO,
kCGRenderingIntentDefault);
CGDataProviderRelease(dataProvider);
// make a bitmap context of a suitable size to draw to, forcing decode
size_t width = CGImageGetWidth(image);
size_t height = CGImageGetHeight(image);
unsigned char *imageBuffer = (unsigned char *)malloc(width*height*4);
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef imageContext =
CGBitmapContextCreate(imageBuffer, width, height, 8, width*4, colourSpace,
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);
CGColorSpaceRelease(colourSpace);
// draw the image to the context, release it
CGContextDrawImage(imageContext, CGRectMake(0, 0, width, height), image);
CGImageRelease(image);
// now get an image ref from the context
CGImageRef outputImage = CGBitmapContextCreateImage(imageContext);
// post that off to the main thread, where you might do something like
// [UIImage imageWithCGImage:outputImage]
[self performSelectorOnMainThread:@selector(haveThisImage:)
withObject:[NSValue valueWithPointer:outputImage] waitUntilDone:YES];
// clean up
CGImageRelease(outputImage);
CGContextRelease(imageContext);
free(imageBuffer);
您也可以使用UIImage+ImmediateLoad.m
它立即解码图像。除了UIImage-initWithContentsOfFile:,-imageWithCGImage:和CG*在iOS4之后是线程安全的。由于您是从网络上获取图像,因此您会落后。您可能希望尝试从另一个调度队列异步获取映像。查找grand central dispatch。这是一个经典的反模式,也是一个非常常见的编程错误。这个问题每周大约被问10次。使用搜索功能可能会发现几十种解决方案。@CouchDeveloper我理解,但我仍然找不到答案,我对其中一部分进行了修复,但tableview仍然滞后。真令人沮丧…在缓存图像时,您应该确保图像也被解码(通过在上下文中绘制位图),并且其当前大小完全适合UIImage的帧。您需要确保在绘制单元之前立即出现这种情况。因此,您可能需要更复杂的缓存策略。不过,上面提到的任何帮助程序库都不能为您实现这一点。当从数据库加载项并实现动态字体大小和动态单元格大小时,我遇到了相同的问题?我使用NSURLConnection sendAsynchronousRequest从json数据获取图像URL。之后,我将URL保存在NSMutableArray中。如何在缓存中保存URL?您可以获取图像URL并将其保存到可变数组中,这很好。更好的方法是使用sendAsynchronousRequest获取实际图像,然后将这些UIImage保存在可变数组中。“作为一种快速解决方案,在视图控制器中实现NSCache并将图像存储在其中。”我对NSCache非常陌生。。如何在NSCache中存储图像?我还应该使用self.alleimages数组吗?简单地说,NSCache的行为几乎是