UIScrollview要加載大量數據的時候,考慮到內存的消耗問題,咱們不可能所有加載完。

所以,須要找到個方法去延遲加載(lazily load), zip.gif9160_ScrollerDemo.zip(164.69 KB, 下載次數: 42),在測試時發現圖片都加載到了內存中,致使內存會愈來愈大,所以會考慮到每次只加載三張,即當前這一張,前一張和後一張!而後釋放掉其餘的內存。具體的代碼以下:
第一步:將要加載的內容先置爲空
php

  1. // view controllers are created lazily 將要加載的內容先置爲空
    app

  2. // in the meantime, load the array with placeholders which will be replaced on demand
    ide

  3. NSMutableArray *controllers = [[NSMutableArray alloc] init];
    測試

  4. for (unsigned i = 0; i < kNumberOfPages; i++)
    ui

  5. {
    spa

  6.      [controllers addObject:[NSNull null]];
    code

  7. }
    圖片

  8. self.viewControllers = controllers;
    ip

  9. [controllers release];內存

複製代碼



第二步:設置加載圖片的方法
  1. - (void)loadScrollViewWithPage:(int)page

  2. {

  3. // 判斷內容頁面是否到了第一或者最後一頁

  4. if (page < 0)

  5.       return;

  6. if (page >= kNumberOfPages)

  7.        return;


  8. // replace the if necessary 加載scrollView裏的該page內容頁面,自定義的MyViewController

  9. MyViewController *controller = [viewControllers objectAtIndex:page];

  10. if ((NSNull *)controller == [NSNull null])

  11. {

  12.    controller = [[MyViewController alloc] initWithPageNumber:page];//自定義的viewController初始方法

  13.    [viewControllers replaceObjectAtIndex:page withObject:controller];//替換以前內容置爲空的相應頁面

  14.   [controller release];

  15. }


  16. // add the controller's view to the scroll view 將已替換的頁面再加入到scrollView中顯示

  17. if (controller.view.superview == nil)

  18. {

  19. CGRect frame = scrollView.frame;//設定該page的frame

  20. frame.origin.x = frame.size.width * page;

  21. frame.origin.y = 0;

  22. controller.view.frame = frame;

  23. [scrollView addSubview:controller.view];


  24. NSDictionary *numberItem = [self.contentList objectAtIndex:page];//加載一些自定義的內容

  25. controller.numberImage.p_w_picpath = [UIImage p_w_picpathNamed:[numberItem valueForKey:ImageKey]];

  26. controller.numberTitle.text = [numberItem valueForKey:NameKey];

  27. }

  28. }

複製代碼




第三步: 而後在滾動的過程當中,scrollView的這個delegate方法被調用,咱們在這個方法去設定加載的內容
  1. - (void)scrollViewDidScroll:(UIScrollView *)sender

  2. {


  3. if (pageControlUsed)

  4. {

  5. // do nothing - the scroll was initiated from the page control, not the user dragging

  6. return;

  7. }


  8. // Switch the indicator when more than 50% of the previous/next page is visible

  9. // 控制在頁面轉到50%的時候設定加載新內容

  10. CGFloat pageWidth = scrollView.frame.size.width;

  11. int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;

  12. pageControl.currentPage = page;


  13. // load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)

  14. [self loadScrollViewWithPage:page - 1];

  15. [self loadScrollViewWithPage:page];

  16. [self loadScrollViewWithPage:page + 1];


  17. // 這裏就能夠本身設定去釋放那些沒有加載的內容了

  18.   [viewControllers replaceObjectAtIndex:page-2 withObject:[NSNull null]];

  19.   [viewControllers replaceObjectAtIndex:page-3 withObject:[NSNull null]];

  20.   [viewControllers replaceObjectAtIndex:page+2 withObject:[NSNull null]];

  21.   [viewControllers replaceObjectAtIndex:page+3 withObject:[NSNull null]];

  22. }


  23. }

  24. }

複製代碼




原本到這裏應該解決了內存不夠的問題,通過測試,後來發現程序仍然有閃退的現象發生,接着用打印內存的方式查看程序的內存狀況,發現滑動到某張圖片的時候,內存忽然暴漲,從30多一會兒暴漲130多,100多M的內存不知道被誰吃掉了,後來通過各類緣由的排查,發現是用 p_w_picpathWithContentsOfFile的方法從documents文件夾中加載圖片的時候,內存會大量增長,解決的辦法是:
爲了防止爆內存,UIImageView在release以前,仍是要把p_w_picpath置nil,
  1. MyScrollView *page1 = [viewControllers objectAtIndex:page-2];

  2.        if ((NSNull *)page1 != [NSNull null])

  3.        {

  4.        page1.p_w_picpathView.p_w_picpath = nil;

  5.        }


複製代碼


到這裏,這個程序纔會以穩定的內存運行,不會出現閃退的現象。


結果,在用uislider滾動的時候,若是是加載當前三張的話,由於uislider不是一次滾動一張,會出現露出白色底色的現象,最後決定在 - (void)didReceiveMemoryWarning 裏面釋放掉不須要的內存。
  1.    for (int i=0; i<currentPage-1; i++) {

  2.        MyScrollView *page_1 = [viewControllers objectAtIndex:i];

  3.        if ((NSNull *)page_1 != [NSNull null])

  4.        {

  5.     page_1.p_w_picpathView.p_w_picpath = nil;

  6.        }

  7.     [viewControllers replaceObjectAtIndex:i withObject:[NSNull null]];

  8.    }


  9.    for (int i=currentPage+1; i<num;i++) {


  10.        MyScrollView *page_2 = [viewControllers objectAtIndex:i];

  11.        if ((NSNull *)page_2 != [NSNull null])

  12.        {

  13.        page_2.p_w_picpathView.p_w_picpath = nil;

  14.        }


  15.        [viewControllers replaceObjectAtIndex:i withObject:[NSNull null]];

  16.        }

相關文章
相關標籤/搜索