糟糕的性能UIScrollView有很多图像

时间:2014-01-03 01:05:37

标签: ios iphone uiscrollview

在我的iOS应用程序中,我有一个UIScrollView,其中有许多带UIImage的UIImageViews。当用户向下滚动时,从Web下载其他图像并将它们添加到滚动视图中。我的问题是,当图像太多(超过50)时,滚动视图变慢但我没有收到任何内存警告。我怎么解决这个问题? 我希望我自己解释一下。

4 个答案:

答案 0 :(得分:3)

以下是答案:uiscrollview-and-lazy-loading

如果您在UIScrollView中加载太多图像时遇到内存问题,延迟加载则是您的答案。

延迟加载描述了一种简单的技术,只能加载应该显示的内容,不再需要。

由于iPhone / iPad / iPod的物理内存较低,因此在UIScrollView中延迟加载图像至关重要。

如果您按照以下四个步骤执行此操作非常简单:

  1. 在您的代理上收听scrollViewDidScroll,就像这样。

  2. 使用已知图像大小计算当前页面。

  3. 查看图片是否已存在,如果没有,请添加。

  4. 不要忘记清理记忆。

  5. 所有步骤的最终组合:

    -(void)scrollViewDidScroll:(UIScrollView *)myScrollView {
     /**
      * calculate the current page that is shown
      * you can also use myScrollview.frame.size.height if your image is the exact size of your scrollview
      */
     int currentPage = (myScrollView.contentOffset.y / currentImageSize.height);
    
     // display the image and maybe +/-1 for a smoother scrolling
     // but be sure to check if the image already exists, you can do this very easily using tags
     if ( [myScrollView viewWithTag:(currentPage +1)] ) {
         return;
     }
     else {
         // view is missing, create it and set its tag to currentPage+1
     }
    
     /**
      * using your paging numbers as tag, you can also clean the UIScrollView
      * from no longer needed views to get your memory back
      * remove all image views except -1 and +1 of the currently drawn page
      */
     for ( int i = 0; i < currentPages; i++ ) {
         if ( (i < (currentPage-1) || i > (currentPage+1)) && [myScrollView viewWithTag:(i+1)] ) {
             [[myScrollView viewWithTag:(i+1)] removeFromSuperview];
         }
     }
    }
    

答案 1 :(得分:0)

如果图像使用的资源太多,您可以缩小图像尺寸:

// compressionFactor is a factor between 0.0 (worst quality) and 1.0 (best quality)
NSData  *imageData = UIImageJPEGRepresentation(image, compressionFactor);
UIImage *newImage = [[UIImage alloc] initWithData:imageData];

编辑:但更好的解决方案是使用图像缓存系统,如SDWebImage。它非常易于使用,并允许您使用占位符加载图像。它还异步加载图像,因此您的UI不会被阻止,它会在应用程序重载之前从缓存中释放图像。你只需加载这样的图像:

[some_uiimageview setImageWithURL:imageURL placeholderImage:[UIImage imageNamed:@"LOADING_IMAGE.png"]];
// where imageUrl is the web address you're loading the image from

SDWebImage Repo

答案 2 :(得分:0)

使用Apple的Image I/O框架。

使用Image IO,您可以:

  • 快速调整图像大小(使用Core Animation为您提供的更好的算法)。
  • 保留有关图片的元数据

如果你想快速上手,Bill Dudney在这个话题上有一本很棒的iBook

https://itunes.apple.com/au/book/all-image-io-you-need-to-know/id601759073?mt=11

这本书有其他有用的花絮:

  • 了解如何缓存图片以供重复使用。
  • 调试此类问题的概述。

答案 3 :(得分:0)

我知道此线程很旧,但是遇到此问题的人都可以查看3rd party库以获得可重复使用的滚动视图。它使用与表视图相同的原理。您只能加载小图像,并仅在显示时以实际尺寸的图像替换。 您可以加载数千张图像而不会影响内存。这是苹果在本机照片应用程序中使用的方式。诀窍是您一次不加载所有图像,但一次不加载。在不影响用户体验的情况下,改善应用程序的内存管理确实很棒。

以下是链接:https://github.com/sumofighter666/ReusableScrollView