0

I have a wallpaper app that has a paged scrollview on the main view. each page of the scrollview displays 9 images. When the view is scrolled I'm loading the next 10 pages of images and set the previous 10 pages uiimages that I've loaded to nil to prevent memory warnings.

The problem is when the view scrolls and so the following method of scrollview gets called, there is few seconds delay before the view can scroll even though I have put the block code that loads new images in dispatch_async. and when I comment out the whole section of the code with dispatch stuff, there is no delay.

If anyone has any idea on why this happens. please please let me know.

Thank you all so much

- (void)scrollViewDidScroll:(UIScrollView *)scrollV
{
float fractionalPage = scrollView.contentOffset.x / self.view.frame.size.width;

if (curPageNum != lround(fractionalPage)) {

    curPageNum = lround(fractionalPage);        

    //display the page number
    pageNumLabel.text = [NSString stringWithFormat:@"%d",curPageNum+1];
    pageNumLabel.alpha = 1.0;
    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(dismissPageNum) userInfo:nil repeats:NO];


    //loading more pages with 9 image in each
    lastLoadedPageNum = MIN(lastLoadedPageNum + 10, numPages - 1);

    dispatch_queue_t getImages = dispatch_queue_create("Getting Images", nil);
    dispatch_async(getImages, ^{

        for (int i = curPageNum + 4 ; i <= lastLoadedPageNum ; i++) {

            int numPicsPerPage = 9;
            if (picsNames.count%9 && i == numPages-1) {

                numPicsPerPage = picsNames.count%9;
            }

            for (int j = 0 ; j < numPicsPerPage ; j++) {

                UIImage *image = [brain imageWith:[picsNames objectAtIndex:(i*9) + j]];

                dispatch_async(dispatch_get_main_queue(), ^{

                    //loading the image to imageview
                    UIImageView *imageView = (UIImageView *)[scrollView viewWithTag:IMAGE_VIEWS_TAG + (i*9) + j];
                    imageView.image = image;
                });
            }
        }
    });

    //setting old imageview images to nil to release memory
    int oldFirstLoadedPageNum = firtLoadedPageNum;
    firtLoadedPageNum = MAX(curPageNum - 4, 0);
    for (int i = oldFirstLoadedPageNum ; i < firtLoadedPageNum ; i++) {

        int numPicsPerPage = 9;
        if (picsNames.count%9 && i == numPages-1) {

            numPicsPerPage = picsNames.count%9;
        }

        for (int j = 0 ; j < numPicsPerPage ; j++) {

            UIImageView *imageView = (UIImageView *)[scrollView viewWithTag:IMAGE_VIEWS_TAG + (i*9) + j];
            imageView.image = nil;
            [((UIActivityIndicatorView *)[imageView viewWithTag:ACTIVITY_INDICATOR_TAG]) startAnimating];
        }            
    }
}
}

Brain method imageWith:

-(UIImage *)imageWith:(NSString *)imageName
{
NSString *imagePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:imageName];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];

if (!image && [self connected]) {

    image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", picsURL, imageName]]]];

    if (image) {

        [UIImagePNGRepresentation(image) writeToFile:imagePath atomically:YES];
    }

}

return image;
}
Mona
  • 5,939
  • 3
  • 28
  • 33

3 Answers3

1

Clearly your code is looping which causes the delay. I think since the dispatch is inside the for loop it gets called only after a certain bit of iterations so that there is no real gain in using multi threading here.

prince
  • 854
  • 2
  • 9
  • 36
  • the main dispatch is outside the for loop. and the delay is caused because of download process not the display proccess – Mona May 16 '13 at 00:46
0

Most likely your logic after the block with the nested for loops is causing the delay. Move that out into a separate method and run it in a separate thread.

savner
  • 830
  • 6
  • 7
  • even when I comment out that section, I still have the delay – Mona May 14 '13 at 20:43
  • The end of your block is inside a for loop - did you mean to have that for loop inside of the dispatch_async? – savner May 14 '13 at 20:48
  • no. inside the for loop after I get each image, I assign it to imageview inside the main queue – Mona May 14 '13 at 20:55
0

As suggested by Mike Pollard I used

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0) 

instead of

dispatch_queue_create("Getting Images", nil) 

and it solved the issue.

Thanks everyone.

Mona
  • 5,939
  • 3
  • 28
  • 33