开发者

How to make ui responsive all the time and do background updating?

I am creating a application which displays 8 thumbnails per page and it can have n pages. Each of these thumbnails are UIViews and are added to UIScrollView. However i have implemented Paging using the Apple sample code.

The prob:

  1. Each thumbnail(UIView) takes 150 millisec开发者_C百科s to be created and added to scroll view
  2. Hence for 3 pages it takes awful huge time to be created and added to the UI Scrollview.
  3. At this point the scroll view is not very respsonsive and it is very jerky and gives a bad user experience
  4. How can i create the thumbnails and add them to UIScrollview without affecting the touch responsiveness? I want them to run independent of the main thread which is resposible for handling touch events (i suppose).

Also i would like to mention that when a thumbnail is created i trigger a Async download of the image and the delegate method is called when download is complete.

Let me know the the options i have to make this more responsive and update UI without affecting the touch operations. The page control works fine with lazy loading of the grid of thumbnails.

TIA,

Praveen S


Grand Central Dispatch is easy to use for background loading. But GCD is only for after iOS4. If you have to support iOS3, performSelectorInBackground/performSelectorOnMainThread or NSOperationQueue are helpful.

And, be careful almost UIKit classes are not thread-safe except drawing to a graphics context. For example, UIScrollView is not thread-safe, UIImage imageNamed: is not thread-safe, but UIImage imageWithContentsOfFile: is thread-safe.

dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_queue_t concurrentQueue =
    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(concurrentQueue, ^{

    dispatch_apply([thumbnails count], concurrentQueue, ^(size_t index) {

        Thumbnail *thumbnail = [thumbnails objectAtIndex:index];
        thumbnail.image = [UIImage imageWithContentsOfFile:thumbnail.url];

        dispatch_sync(mainQueue, ^{

            /* update UIScrollView using thumbnail. It is safe because this block is on main thread. */

        });
    }

    /* dispatch_apply waits until all blocks are done */

    dispatch_async(mainQueue, ^{
        /* do for all done. */
    });
}


I was having a similar problem.
What i did was at an instance i kept only 3 pages in the memory and cleared remaining all.
If suppose there are 3 screens s1, s2, s3. And the user is viewing s2. Whenever he scrolls to s3 i will remove s1 and load a new page s4.
So that the users will have a better experience. And less memory will be occupied.


Whether you are using a subview or a separate ViewController for each "page" or element of the Scrollview, the jerkiness or poor performance can be helped by changing the location of your code.

Specifically the apple sample code for a scrollview with pagecontrol has something like this:

[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];

However, that code appears in their sample in the method "scrollViewDidScroll". It's trying to do multiple heavy lifting by both scrolling and loading at the same time. Even if your images are local this is nasty.

If you move this and related code including a reference to the current page to "scrollViewDidEndDecelerating" the jerkiness of the interface is resolved because the loading happens while the scrollview is no longer moving.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜