UIScrollView lazy loading of images to reduce memo

2019-02-07 20:57发布

问题:

My app, using scrollview that loads multiple images with NSOperation (Max around 100sh). I tried to test it out on my ipod 2Gen and it crashes due to low memory on device, but works fine on ipod 4th Gen. On 2nd Gen, it crashes when it loads about 15-20 images. How should I handle this problem ?

回答1:

You could load you images lazily. That means, e.g., just a couple of images at a time in your scroll view, so that you can animate to the next and the previous one; when you move to the right, e.g., you also load one more image; at the same time, you unload images that are not directly accessible anymore (e.g. those that have remained to the left).

You should make the number of preloaded image sufficiently high so that the user can scroll without waiting at any time; this also depends on how big those images are and where they come from (i.e., how long it takes to load them)... a good starting point would be, IMO, 5 images loaded at any time.

Here you will find a nice step by step tutorial.

EDIT:

Since the link above seems to be broken, here is the final code from that post:

-(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];
    }
}
}