2

使用:

  • iOS 5、ARC、故事板。

每个单元格上都有 1 个图像和文本。滚动时图像不会调整大小。有两个版本的图像 image.png 和 image@2x.png。

自定义单元格是通过在情节提要中使用 UIImageView 和 UILabel 来管理的。

代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
Continent *continent=[self.items objectAtIndex:[indexPath row]];
ContinentCell *cell = (ContinentCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    cell.continentName.text=continent.continentName;
    cell.textView.text=continent.countriesHash;
    cell.imageView.image=[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:continent.continentImage ofType:@"png"]];
 return cell;
}

邪恶在哪里?先感谢您。

4

4 回答 4

12
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:continent.continentImage ofType:@"png"]];

太贵了。您想在后台异步加载图像,然后在准备好时将其呈现在主线程上。

这是一个非常粗略的解决方案

    cell.imageView.image = nil;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      UIImage * img = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:continent.continentImage ofType:@"png"]];
      dispatch_sync(dispatch_get_main_queue(), ^{
        cell.imageView.image = img;
      });
    });
于 2012-06-28T18:04:28.560 回答
5

查看26:48 WWDC 2011的抛光您的应用程序:提高响应性和性能的提示和技巧视频。他们已经准确地讨论了您所面临的问题。不要错过,这将是非常有帮助的..!

于 2012-06-29T03:34:21.797 回答
2

确保您的图像不大,然后:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    Continent *continent=[self.items objectAtIndex:[indexPath row]];
    ContinentCell *cell = (ContinentCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if(cell == nil) cell = [[ContinentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]
    cell.continentName.text = continent.continentName;
    cell.textView.text = continent.countriesHash;
    cell.imageView.image = [UIImage imageNamed:continent.continentImage];
    return cell;
}

我做了两个重大的改变:

  1. 补充if(cell == nil) [[ContinentCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier],因为我没有找到初始化单元格的代码(除非你使用-registerNib或其他超级sectet函数,我不能说,因为它在NDA下)

  2. 替换imageWithContentsOfFile:...为 simple imageNamed,因为您从主包中加载图像,并且如果图像不大,-imageNamed则将其缓存,因此加载速度更快。(并且 -imageNamed 不需要文件扩展名)

于 2012-06-28T18:10:50.857 回答
2
- (UITableViewCell *)tableView:(UITableView *)tableView 
                                 cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    Continent *continent=[self.items objectAtIndex:[indexPath row]];
    ContinentCell *cell = (ContinentCell*)[tableView 
                               dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[ContinentCell alloc] 
                               initWithStyle:UITableViewCellStyleDefault 
                               reuseIdentifier:CellIdentifier];
     }
    cell.continentName.text=continent.continentName;
    cell.textView.text=continent.countriesHash;
    //cell.imageView.image=[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] 
                        pathForResource:continent.continentImage ofType:@"png"]];
    cell.imageView.image = [UIImage cachedImage:continent.continentImage];
    return cell;
}

我会推荐你​​使用 imageNamed 而不是 imageWithContentsOfFile。

imageNamed方法将图像加载到缓存中,下次它将从缓存中加载,其中 imageWithContentsOfFile 方法从您指定的路径加载图像而不进行NO缓存,它将在内存中创建多个副本。

您可以创建自己的图像缓存方法。只需声明 NSMutableDictionary *imagedCacheDict

如果内存不足,可以通过 [imagedCacheDict removeAllObjects]删除所有对象

 - (UIImage*)cachedImage:(NSString*)fileName
{
   UIImage *cacheImage = [imagedCacheDict objectForKey:fileName];

   if (nil == cacheImage)
   {
      NSString *cacheImageFile = [NSString stringWithFormat:@"%@.png", 
                                   [[NSBundle mainBundle] resourcePath], fileName];
      cacheImage = [UIImage imageWithContentsOfFile:cacheImageFile];
      [imagedCacheDict setObject:cacheImage forKey:fileName];
   }
   return cacheImage;
}

所以,永远不要使用 imageNamed 方法,它会消耗大量内存来带出你的应用程序。

于 2012-06-28T18:16:10.677 回答