滚动性能和UIImage绘图

sam*_*tte 4 iphone performance scroll image uitableview

我正在构建一个类似于iPod.app的专辑浏览视图的UITableView:

IMG_2316.PNG

我是在首次推出时从iPod库导入所有艺术家和专辑作品.将所有内容保存到CoreData并将其恢复为NSFetchedResultsController.我正在重用单元格标识符,在我的cellForRowAtIndexPath:方法中我有这个代码:

Artist *artist = [fetchedResultsController objectAtIndexPath:indexPath];
NSString *identifier = @"bigCell";

SWArtistViewCell *cell = (SWArtistViewCell*)[tableView dequeueReusableCellWithIdentifier:identifier];

if (cell == nil)
    cell = [[[SWArtistViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];

cell.artistName = artist.artist_name;
cell.artworkImage = [UIImage imageWithData:artist.image];

[cell setNeedsDisplay];

return cell;
Run Code Online (Sandbox Code Playgroud)

我的SWArtistViewCell单元格实现了drawRect:绘制字符串和图像的方法:

[artworkImage drawInRect:CGRectMake(0,1,44,44)]
[artistName drawAtPoint:CGPointMake(54, 13) forWidth:200 withFont:[UIFont boldSystemFontOfSize:20] lineBreakMode:UILineBreakModeClip];
Run Code Online (Sandbox Code Playgroud)

滚动仍然不稳定,我只是无法弄清楚原因.像iPod和Twitter这样的应用程序有黄油平滑滚动,但他们都像我一样在单元格中绘制一些小图像.

我的所有观点都是不透明的.我错过了什么?

编辑:这是Shark所说的:

替代文字

我不熟悉鲨鱼.任何指针与这些符号有什么关系?当我看到这些的痕迹时,它们都指向我的drawRect:方法,特别是UIImage绘图.

替代文字

如果扼杀是文件读取,它会指向别的东西吗?这绝对是绘画吗?

编辑:保留图像

我已经按照pothibo的建议完成了,并将一个artworkImage方法添加到我的Artist类中,该类保留了使用imageWithData创建的图像:

- (UIImage*)artworkImage {
    if(artworkImage == nil)
        artworkImage = [[UIImage imageWithData:self.image] retain];

    return artworkImage;
}
Run Code Online (Sandbox Code Playgroud)

所以现在我可以直接将保留的图像设置为我的TableViewCell,如下所示:

cell.artworkImage = artist.artworkImage;
Run Code Online (Sandbox Code Playgroud)

我还在我的tableViewCell类的setArtworkImage:方法中设置了setNeedsDisplay.滚动仍然是滞后的,Shark显示完全相同的结果.

Jon*_*röm 6

您的分析数据强烈暗示瓶颈在于解压缩PNG图像.我的猜测是,你提供的CPU时间的58.5%用于解压缩PNG数据(即如果memcpy调用也包含在加载中).可能更多的时间花在那里,但没有更多的数据很难说.我的建议:

  1. 如前所述,将加载的图像保留在UIImage中,而不是NSData中.这样,每次显示图像时都不必进行PNG解包.
  2. 将图像加载到工作线程中,不会影响主线程的响应性(同样多).创建一名工人非常容易:

    [self performSelectorOnMainThread:@selector(preloadThreadEntry :) withObject:nil waitUntilDone:NO];

  3. 预先加载图像,例如100行或更多(在您滚动的方向上为70,在相反方向上保持30).如果您的所有图像在视网膜上需要88x88像素,则100张图像需要不超过2 MB.

  4. 当您分析更多对名为"png","gz","inflate"等内容的调用可能不会在您的列表中显示,但它们肯定不会以如此糟糕的方式影响应用程序的感觉.

只有在此之后您仍然遇到性能问题,我建议您研究缩放,例如为视网膜加载"... @ 2x.png"图像.祝好运!