objective-c - UITableView 仍然很慢,有 block

标签 objective-c

所以我的应用程序中有一个 tableView,它基本上运行 Facebook 上一些用户 friend 的姓名和图像。 问题是,当我上下拖动 tableView 时,它很慢而且不流畅,尽管我使用 block 从 Facebook 上传图像 - 所以它是异步的。 现在,在我实现了从 Facebook 上传图像的 block 之后,它的运行速度比 block 之前更快 - 但仍然不够流畅。

有人知道怎么处理吗? 这是我的一些代码:

cellForRowAtIndexPath:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"friendCell"];
   if (cell == nil) {
      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                          reuseIdentifier:@"friendCell"];
      [friendsTableView reloadData];
   }

   //set data for user's friends images
   NSURL *url;
   NSString *stringID;
   stringID = [[NSString alloc]initWithFormat:@"https://graph.facebook.com/%@/picture?type=square",facebookFriendsID[indexPath.row] ];
   url = [NSURL URLWithString:stringID];

   //Calling block function to hendle user's friends images from facebook
   [self downloadImageWithURL:url :stringID :cell completionBlock:^(BOOL succeeded, UIImage *image) {
       if (succeeded) {
          cell.imageView.image = image;
       }
   }];

   //For friends name...
   cell.textLabel.text = facebookFriendsName[indexPath.row];
   cell.textLabel.font = [UIFont fontWithName:@"Noteworthy" size:17.0f];
   [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
   cell.imageView.layer.masksToBounds = YES;
   cell.imageView.layer.cornerRadius = 25.0;

   return cell;

}

和 downloadImage block :

//For upload the images from Facebook asynchrony- using block.
- (void)downloadImageWithURL:(NSURL *)url : (NSString *)string : (UITableViewCell *)cell completionBlock:(void (^)(BOOL succeeded, UIImage *image))completionBlock
{

   NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
   [NSURLConnection sendAsynchronousRequest:request
                                   queue:[NSOperationQueue mainQueue]
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                           if ( !error )
                           {
                               UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];

                               completionBlock(YES,image);

                           } else{
                               completionBlock(NO,nil);
                           }
                       }];
}

谢谢! :)

最佳答案

您的代码有 4 个问题,所有这些问题都会导致速度缓慢:

  1. 删除[friendsTableView reloadData]; - 切勿从cellForRowAtIndexPath:内部重新加载表格。
  2. 您不应从完成 block 内引用cell:

    [self downloadImageWithURL:url :stringID :cell completionBlock:^(BOOL succeeded, UIImage *image) {
        if (succeeded) {
            cell.imageView.image = image;
        }
    }];
    

    下载图片时,cell 可能已被重复使用并显示不同的内容。这可能会导致出现错误的头像图像。相反,使用 indexPath 通过调用 UITableViewCell *currentCell = [tableView cellForRowAtIndexPath:indexPath]; 获取当前单元格,并在其上设置图像。

  3. 每次出现单元格时,您都会创建一个新的网络请求。如果用户滚动速度非常快,您将有大量同时发生的网络请求。当 ScrollView 减慢时,您可能希望在 scrollViewDidScroll: 中启动网络请求。
  4. 您没有对网络请求进行重复数据删除。如果用户上下滚动速度非常快,他们将会对同一 URL 生成大量网络请求。您需要缓存已下载的图像,并在已发出网络请求时使用这些图像。*

SDWebImage 库已经解决了所有这些问题;您可能只是想使用它而不是重新发明轮子。至少,值得阅读他们的代码:https://github.com/rs/SDWebImage


* - NSURLCache 可能会为您缓存图像,具体取决于服务器的 cache-control header 。但即便如此,这个缓存还是很慢(它缓存 NSData 表示,而不是 UIImage 表示),并且 NSURLConnection 不会阻止您同时启动 4 个相同的请求。

关于objective-c - UITableView 仍然很慢,有 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21815568/

相关文章:

ios - 自动调整大小不以编程方式工作

iphone - 为什么这个NSMutableSet不会泄漏内存

objective-c - 我应该在 Objective C 中的什么地方放置一个全局效用函数?

iphone - 核心图从 NSMutableArray 添加数据

objective-c - Cocoa 中的双向映射

ios - 在 NSDictionary 初始化中使用时 NSNumber 变为 nil

ios - NSURLSession 和多线程

objective-c - 核心数据: concurency conflict between save and fetch

iphone - objective-c : UIColor * exception 'NSInvalidArgumentException?

ios - 你如何创建一个对象的 NSMutableArray,它不会增加添加到它的每个对象的保留计数?