为什么我的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] }); });