我有一个UITableView,它使用reuseCellIdentifier并包含图像(使用UIImageView + AFNetworking.h异步下载);可以预料,在滚动一段时间后,当桌子变长时,它会变得缓慢。我还将从互联网下载的每个单元格的数据存储在NSMutableArray *_collection
中,因此每次单元格重新进入视图时,我都不会再次重新加载。
我的问题是,在使用以下方法完全刷新表格之后,滚动仍然非常缓慢。使其再次平滑的唯一方法是退出应用程序并重新打开它。我不明白为什么重新加载后滚动仍然缓慢...我正在使用ARC,我做了泄漏的配置文件,当我重新加载表时看不到任何内容..
-(void)refreshTable:(id)sender{
[_collection removeAllObjects];
_collection = nil;
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:_baseURL]];
[httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST" path:_path parameters:nil];
AFJSONRequestOperation *operation = [AFJSONRequestOperation ...etc...
更进一步,我甚至尝试在刷新时删除tableview,如下所示,但它也无济于事......
-(void)refreshTable:(id)sender{
[_tableView removeFromSuperView];
_tableView = nil;
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
[_tableView setDelegate:self];
[_tableView setDataSource:self];
[_tableView setRowHeight:kRowHeight];
[_tableView setBackgroundColor:[UIColor clearColor]];
[_tableView setSeparatorColor:[UIColor clearColor]];
[_tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
[self.view addSubview:_tableView];
[_collection removeAllObjects];
_collection = nil;
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:_baseURL]];
[httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST" path:_path parameters:nil];
AFJSONRequestOperation *operation = [AFJSONRequestOperation ...etc...
刷新表后滚动仍然缓慢的原因可能是什么?谢谢!
修改
- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = (CustomCell*)[theTableView dequeueReusableCellWithIdentifier:kCustomCellId];
if (cell == nil)
{
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
cell = (CustomCell*)[topLevelObjects objectAtIndex:0];
}
[self populate:cell atIndexPath:indexPath];
[self loadImageForCell:cell];
return cell;
}
- (void) populate:(UITableViewCell*)customCell atIndexPath:(NSIndexPath*)indexPath
{
CustomCell *cell = (CustomCell*)customCell;
if (indexPath.row % 2) {
[cell.background setImage:[UIImage imageNamed:@"CellBgYellow"]];
} else {
[cell.background setImage:[UIImage imageNamed:@"CellBgOrange"]];
}
DataObject* thisDataObject = [_collection objectAtIndex:indexPath.row];
cell.dataObject = thisDataObject;
cell.titleLabel.text = [thisDataObject objectForKey:kCellTitle];
cell.timestampLabel.text = [thisDataObject objectForKey:kCellTimestamp];
}
- (void) loadImageForCell:(CustomCell*)cell
{
[cell.profilePic setImage:nil];
NSString* profilePicURL = [cell.dataObject objectForKey:kCellProfilePicURL];
NSString* URL = [NSString stringWithFormat:@"%@%@", kBaseURL, profilePicURL];
NSMutableURLRequest *profilePicRequest = [NSMutableURLRequest requestWithURL:[[NSURL alloc] initWithString:URL] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
[profilePicRequest setHTTPShouldHandleCookies:NO];
[cell.profilePic setImageWithURLRequest:profilePicRequest
placeholderImage:nil
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image){
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){
NSLog(@"loadimageforcell error (%d): %@",error.code,error.localizedDescription);
}];
[cell.painting setImage:nil];
NSString* paintingURL = [cell.dataObject objectForKey:kCellPaintingURL];
URL = [NSString stringWithFormat:@"%@%@", kBaseURL, paintingURL];
NSMutableURLRequest *paintingRequest = [NSMutableURLRequest requestWithURL:[[NSURL alloc] initWithString:URL] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
[paintingRequest setHTTPShouldHandleCookies:NO];
[cell.spinner startAnimating];
[cell.painting setImageWithURLRequest:paintingRequest
placeholderImage:nil
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image){
[cell.spinner stopAnimating];
[cell.spinner removeFromSuperview];
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error){
NSLog(@"loadimageforcell error (%d): %@",error.code,error.localizedDescription);
[cell.spinner stopAnimating];
[cell.spinner removeFromSuperview];
}];
}
答案 0 :(得分:1)
问题是2:
根据图像尺寸,您必须做各种事情。 最简单,最明显的解决方案是在另一个线程中解压缩图像。 这样你的主线程就不会被阻挡,滚动性能也会得到很好的提升。
以下是一段代码,可以帮助您:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^(void) {
UIImage *cellImage = [UIImage imageWithContentsOfFile:imgFilePath];
dispatch_async(dispatch_get_main_queue(),^ {
cellImageView.image = cellImage;
} );
});
正如您所看到的,UIImage是在后台线程中生成的,只要我们解码了图像,我们就会将其分配给单元格。
在上面的示例中,图像被预先缓存,imgFilePath是缓存图像的docments目录的路径。
使用Loren Brichter的ABTableView单元子类并使用Core Graphics绘制图像(也可以提高性能),您可以继续使用其他各种方法来提高性能。 最后,如果图像很大,你可以将整个单元格设置为CATiledLayer类的子类,这样图像的绘制也可以由系统在后台线程中完成......
答案 1 :(得分:0)
请勿在cellForRowAtIndexPath中加载图片。那只会扼杀你的滚动。
要快速解决问题,请仅在桌面视图未滚动时完全停止加载图片。
更好的方法是重新思考你的设计。通过使用网络队列和延迟加载图像是可行的方法。
查看Lazy TableView的苹果演示:http://developer.apple.com/library/ios/#samplecode/LazyTableImages/Introduction/Intro.html
这教会了我很多,通过像你一样使用ASIHTTPRequest,你甚至可以让这更简单。但是看看代码,它评论很好且易于理解
**因为您使用afnetwork而更新
这样做f.ex.在你的cellForRowAtIndexPath里面:
NSURLRequest *imagerequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/image.png"]];
AFImageRequestOperation *op = [AFImageRequestOperation imageRequestOperationWithRequest:imagerequest success:^(UIImage *image) {
cell.imageview.image = image;
}];