为什么我的tableview很慢?

即时通讯使用一些NSArrays加载tableview,单元格包含两个标签和一个URL图像加载的背景图像视图。 问题是,滚动的tableview是缓慢的,像冻结或东西….我认为这是因为Imageview,但我能做什么?

inheritance人一些我的代码,所以你可以看到:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // Return the number of rows in the section. return _Title.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; MyCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; int row = [indexPath row]; cell.TitleLabel.text = _Title[row]; cell.DescriptionLabel.text = _content[row]; cell.CellImageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:_ImageUrl[row]]]]; cell.CellImageView.contentMode = UIViewContentModeTop; cell.CellImageView.contentMode = UIContentSizeCategoryMedium; cell.backgroundColor = [UIColor clearColor]; return cell; } 

对于额外的信息,这个tableview呈现一个Detailviewcontroller与这个相同的信息。

您使用以下代码行来阻止主线程:

 cell.CellImageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:_ImageUrl[row]]]]; 

我的build议是使用AFNetworking并用以下代码replace代码:

 [cell.cellImageView setImageWithURL:[NSURL URLWithString:@"http://example.com/image.png"]]; 

另外,你的指针应该以小写字母开头。 例如,CellImageView应该是cellImageView。

asynchronous加载图像(随着图像的进入加载)。 看看很好的类,如SDWebImage https://github.com/rs/SDWebImage

你正在从cellForRowAtIndexPath调用[NSData dataWithContentsOfURL:[NSURL URLWithString:_ImageUrl[row]]] ,这不是个好主意。 因为每次加载UITableViewCell时它都会去服务器。

您必须使用asynchronous映像加载和caching。 这些库可能会帮助你:(我个人最喜欢的是SDWebImage

1) https://github.com/rs/SDWebImage

2) https://github.com/nicklockwood/AsyncImageView

更多的,你可以参考苹果关于LazyTableImages的示例代码 – https://developer.apple.com/library/ios/samplecode/LazyTableImages/Introduction/Intro.html

更新:

对于SDWebImage遵循本指南。 这很好。

http://iosmadesimple.blogspot.in/2013/04/lazy-image-loading.html

为了扩展@ vborra的答案 – 你的tableview慢的原因是(在你的代码中)整个图像必须在显示之前完成下载。

这是因为dataWithContentsOfURL:是同步方法。 您需要使用asynchronousAPI在后台下载图像,并在完成下载后将其显示在屏幕上。

这是一个来自github页面的代码片段,适用于您的示例。 确保您将文件夹SDWebImage和它的内容从https://github.com/rs/SDWebImage添加到您的项目中。

 #import <SDWebImage/UIImageView+WebCache.h> ... - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; MyCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; int row = [indexPath row]; cell.TitleLabel.text = _Title[row]; cell.DescriptionLabel.text = _content[row]; [cell.CellImageView setImageWithURL:[NSURL URLWithString:_ImageUrl[row]] placeholderImage:[UIImage imageNamed:@"placeholder.png"]]; cell.CellImageView.contentMode = UIViewContentModeTop; cell.CellImageView.contentMode = UIContentSizeCategoryMedium; cell.backgroundColor = [UIColor clearColor]; return cell; } 

请注意,如果您正在下载所有不同尺寸的图片,则最终可能会resize,这也会降低您的效果。 SDWebImage页面提供了一篇文章的链接,以帮助您解决这个问题。 http://www.wrichards.com/blog/2011/11/sdwebimage-fixed-width-cell-images/

在使用透明度和表格视图时,您也可能会遇到性能下降,但这取决于您的其他代码。

AFNetworking是一个很好的使用工具,但如果你没有在你的应用程序的其他地方使用networking,可能会过度。

像这样加载你的图片

 //get a dispatch queue dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //this will start the image loading in bg dispatch_async(concurrentQueue, ^{ NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:mapUrlStr]]; //this will set the image when loading is finished dispatch_async(dispatch_get_main_queue(), ^{ cell.CellImageView.image = [UIImage imageWithData:imageData] }); });