UIScrollview要加载大量数据的时候,考虑到内存的消耗问题,我们不可能全部加载完。

    因此,需要找到个方法去延迟加载(lazily load), 9160_ScrollerDemo.zip (164.69 KB, 下载次数: 42)  ,在测试时发现图片都加载到了内存中,导致内存会越来越大,因此会考虑到每次只加载三张,即当前这一张,前一张和后一张!然后释放掉其他的内存。具体的代码如下:
第一步:将要加载的内容先置为空
  1. // view controllers are created lazily 将要加载的内容先置为空
  2. // in the meantime, load the array with placeholders which will be replaced on demand
  3. NSMutableArray *controllers = [[NSMutableArray alloc] init];
  4. for (unsigned i = 0; i < kNumberOfPages; i++)
  5. {
  6.       [controllers addObject:[NSNull null]];
  7. }
  8. self.viewControllers = controllers;
  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.image = [UIImage imageNamed:[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的内存不知道被谁吃掉了,后来经过各种原因的排查,发现是用 imageWithContentsOfFile的方法从documents文件夹中加载图片的时候,内存会大量增加,解决的办法是:
为了防止爆内存,UIImageView在release之前,还是要把image置nil,
  1. MyScrollView *page1 = [viewControllers objectAtIndex:page-2];
  2.         if ((NSNull *)page1 != [NSNull null])
  3.         {
  4.         page1.imageView.image = 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.imageView.image = nil;
  6.         }
  7.      [viewControllers replaceObjectAtIndex:i withObject:[NSNull null]];
  8.     }
  9.             
  10.     for (int i=currentPage+1; i<num;i++) {
  11.         
  12.         MyScrollView *page_2 = [viewControllers objectAtIndex:i];
  13.         if ((NSNull *)page_2 != [NSNull null])
  14.         {
  15.         page_2.imageView.image = nil;
  16.         }
  17.                 
  18.         [viewControllers replaceObjectAtIndex:i withObject:[NSNull null]];
  19.         }
复制代码
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值