Ios 向上滚动时,UITableView变慢

Ios 向上滚动时,UITableView变慢,ios,objective-c,uitableview,Ios,Objective C,Uitableview,解决方案:使用SDWebImage: 我有一个UITableView,在滚动时会变得非常滞后。我发现当我正在使用的图像返回屏幕时会出现延迟 我正在使用自定义UITableViewCell。这也是它落后的原因吗 我的自定义UITableViewCell: 我的代码: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *

解决方案:使用SDWebImage:

我有一个UITableView,在滚动时会变得非常滞后。我发现当我正在使用的图像返回屏幕时会出现延迟

我正在使用自定义UITableViewCell。这也是它落后的原因吗

我的自定义UITableViewCell:

我的代码:

- (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异步下载您的图像。您将能够消除应用程序中的延迟。:-)
// 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的行为几乎是