百恒网络
IOS开发之资源文件的延迟加载方法
  • 百恒服务
  • APP开发
  • 网页案例
  • 网页知识
  • 关于我们
  • 联系我们
  • IOS开发之资源文件的延迟加载方法

    2017-09-11 15:41:17 3654
           延迟加载指一些对象不是在应用和视图等初始化时创建,而是在用到它的时候创建。当应用中有一些对象并不经常使用时,延迟加载可以提高程序性能。  
           首先,我们要考虑的就是对资源文件的延迟加载。由于资源文件的访问涉及IO操作,这本身就会耗费一定的 CPU时间,如果文件比较大而且加载时机又不合适,就会造成内存浪费。无论是什么类型的文件,有些情况下采用延迟加载是很有必要的。 
    如图1所示的需求,南昌APP开发公司小编认为可以使用分屏控件(UIPageControl)左右滑动屏幕来浏览这3张图片。

    图1 图片延迟加载实例 

           PageControlNavigation实例是没有采用延迟加载的实现代码,其中的ViewController代码如下: 
           class ViewController: UIViewController, UIScrollViewDelegate { 
           var page1 : UIImageView!   
           var page2 : UIImageView!     
           var page3 : UIImageView! 

           @IBOutlet weak var scrollView: UIScrollView!    
           @IBOutlet weak var pageControl: UIPageControl! 

           override func viewDidLoad() {         
           super.viewDidLoad()                  
           self.scrollView.delegate = self                  
           self.scrollView.contentSize              
           = CGSizeMake(self.view.frame.size.width*3, self.scrollView.             
           frame.size.height)         
           self.scrollView.frame = self.view.frame                  
           var mainStoryboard = self.storyboard!                  
           self.page1 = UIImageView(image: UIImage(named: "达芬奇-蒙娜丽莎.png"))        
           self.page1.frame = CGRectMake(0.0, 0.0, 320.0, 480.0)           
           self.page2 = UIImageView(image: UIImage(named: "罗丹-思想者.png"))         
           self.page2.frame = CGRectMake(320.0, 0.0, 320.0, 480.0)                  
           self.page3 = UIImageView(image: UIImage(named: "保罗克利-肖像.png"))        
           self.page3.frame = CGRectMake(2 * 320.0, 0.0, 320.0, 480.0)                          
           self.scrollView.addSubview(page1)         
       
           self.scrollView.addSubview(page2)         

           self.scrollView.addSubview(page3)

           #import "ViewController.h"  
           @interface ViewController ()  
           @property (strong, nonatomic) UIImageView *page1; 
           @property (strong, nonatomic) UIImageView *page2; 
           @property (strong, nonatomic) UIImageView *page3;  
           @property (weak, nonatomic) IBOutlet UIScrollView *scrollView; 
           @property (weak, nonatomic) IBOutlet UIPageControl *pageControl;  
           - (IBAction)changePage:(id)sender;  
           @end  
           @implementation ViewController  
           - (void)viewDidLoad 

           {     

            [

           super viewDidLoad];          
           self.scrollView.delegate = self;         
           self.scrollView.contentSize           
           = CGSizeMake(self.view.frame.size.width*3,      
           self.scrollView.frame.size.height);     
           self.scrollView.frame = self.view.frame;              

           self.page1 = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f,          

           self.view.frame.size.width, self.view.frame.size.height)];     

           self.page1.image = [UIImage imageNamed:@"达芬奇-蒙娜丽莎.png"];          

           self.page2 = [[UIImageView alloc] initWithFrame:CGRectMake(320.0f, 0.0f,         

           self.view.frame.size.width, self.view.frame.size.height)];    

           self.page2.image = [UIImage imageNamed:@"罗丹-思想者.png"]; 

           }  
           override func didReceiveMemoryWarning() {         
           super.didReceiveMemoryWarning()     
           }  
        
           func scrollViewDidScroll(scrollView: UIScrollView) {         
           var offset = scrollView.contentOffset         
           self.pageControl.currentPage = Int(offset.x) / 320     
           }          
           @IBAction func changePage(sender: AnyObject) {         
           UIView.animateWithDuration(0.3,animations : {             
           var whichPage = self.pageControl.currentPage             
           self.scrollView.contentOffset = CGPointMake                 
           (320 * CGFloat(whichPage), 0)         
           })    
           } 
           } 

           self.page3 = [[UIImageView alloc] initWithFrame:CGRectMake(2 * 320.0f, 0.0f,         

           self.view.frame.size.width, self.view.frame.size.height)];     

           self.page3.image = [UIImage imageNamed:@"保罗克利-肖像.png"];          
           [self.scrollView addSubview:self.page1];     
           [self.scrollView addSubview:self.page2];     
           [self.scrollView addSubview:self.page3]; 
           }  
     
           - (void) scrollViewDidScroll: (UIScrollView *) aScrollView 
           {     
           CGPoint offset = aScrollView.contentOffset;     
           self.pageControl.currentPage = offset.x / 320.0f; 
           }   
           - (void)didReceiveMemoryWarning 
           {     
           [super didReceiveMemoryWarning]; 
           }  
           #pragma mark -  
           #pragma mark PageControl stuff 
           - (IBAction)changePage:(id)sender 
           {     
           [UIView animateWithDuration:0.3f animations:^{         
           NSInteger whichPage = self.pageControl.currentPage;         
           self.scrollView.contentOffset = CGPointMake(320.0f * whichPage, 0.0f);    
           }]; 
           }  
           @end

           我们是在viewDidLoad方法中一次加载全部3张图片,但是有的时候用户不一定会浏览后面的图片,他可能只看 到第一张或第二张,后面的第三张没有去看,此时后面的两张图片仍然加载内存的话,会造成内存浪费。 

           这时候我们就可以采用资源文件的延迟加载功能,采用延迟加载实现时,ViewController的代码如下: 

           class ViewController: UIViewController, UIScrollViewDelegate {  
           var page1 : UIImageView!     
           var page2 : UIImageView!     
           var page3 : UIImageView!          
           @IBOutlet weak var scrollView: UIScrollView!     
           @IBOutlet weak var pageControl: UIPageControl!          

           override func viewDidLoad() {         
           super.viewDidLoad()                  
           self.scrollView.delegate = self  
                    
           self.scrollView.contentSize               
           = CGSizeMake(self.view.frame.size.width*3, self.scrollView.             
           frame.size.height)         
           self.scrollView.frame = self.view.frame                  
           var mainStoryboard = self.storyboard!                  
           self.page1 = UIImageView(image: UIImage(named:             
           "达芬奇-蒙娜丽莎.png"))                        ①        

           self.page1.frame = CGRectMake(0.0, 0.0, 320.0, 480.0)                  

           self.scrollView.addSubview(page1)              

           } 

           #import "ViewController.h"  
           @interface ViewController ()  
           @property (strong, nonatomic) UIImageView *page1; 
           @property (strong, nonatomic) UIImageView *page2; 
           @property (strong, nonatomic) UIImageView *page3; 
     
           @property (weak, nonatomic) IBOutlet UIScrollView *scrollView; 
           @property (weak, nonatomic) IBOutlet UIPageControl *pageControl;  

           - (IBAction)changePage:(id)sender;  
           -(void)loadImage:(NSInteger)nextPage;  
           @end  

           @implementation ViewController  
           - (void)viewDidLoad 
           {     
           [super viewDidLoad];          
           self.scrollView.delegate = self;          

           self.scrollView.contentSize  = CGSizeMake(self.view.frame.size.width*3,         

           self.scrollView.frame.size.height);    

           self.scrollView.frame = self.view.frame; 

           override func didReceiveMemoryWarning() {         
           super.didReceiveMemoryWarning()     
           }  
           func scrollViewDidScroll(scrollView: UIScrollView) {         
           var offset = scrollView.contentOffset         
           self.pageControl.currentPage = Int(offset.x) / 320                  
           self.loadImage(self.pageControl.currentPage + 1)              
           }          
           @IBAction func changePage(sender: AnyObject) {         
           UIView.animateWithDuration(0.3,animations : {             
           var whichPage = self.pageControl.currentPage             
           self.scrollView.contentOffset = CGPointMake                 
           (320 * CGFloat(whichPage), 0)             
           self.loadImage(self.pageControl.currentPage + 1)         
           })     
           }          
           func loadImage(nextPage: Int) {                          

           if nextPage == 1 && self.page2 == nil {             
           self.page2 = UIImageView(image: UIImage(named: "罗丹-思想者.png"))             
           self.page2.frame = CGRectMake(320.0, 0.0, 320.0, 480.0)             
           self.scrollView.addSubview(page2)         
           }                           

           if nextPage == 2 && self.page3 == nil {             

           self.page3 = UIImageView(image: UIImage(named: "保罗克利-肖像.png"))                

           self.page3.frame = CGRectMake(2 * 320.0, 0.0, 320.0, 480.0)             

           self.scrollView.addSubview(page3)         

           }    
           } 
           } 

           self.page1 = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f,          

           self.view.frame.size.width, self.view.frame.size.height)];     

           self.page1.image = [UIImage imageNamed:@"达芬奇-蒙娜丽莎.png"];        ①        

           [self.scrollView addSubview:self.page1]; 

           }  
           - (void) scrollViewDidScroll: (UIScrollView *) aScrollView 
           {     
           CGPoint offset = aScrollView.contentOffset;     
           self.pageControl.currentPage = offset.x / 320.0f;     
           [self loadImage:self.pageControl.currentPage + 1]; 
           }  
           - (void)didReceiveMemoryWarning 
           {     
           [super didReceiveMemoryWarning]; 
           }  
           #pragma mark -  
           #pragma mark PageControl stuff 
           - (IBAction)changePage:(id)sender 
           {     
           [UIView animateWithDuration:0.3f animations:^{         
           NSInteger whichPage = self.pageControl.currentPage;         
           self.scrollView.contentOffset = CGPointMake(320.0f * whichPage, 0.0f);        
           [self loadImage:self.pageControl.currentPage + 1];     
           }]; 
           }  
           -(void)loadImage:(NSInteger)nextPage 
           {     
           if (nextPage == 1 && self.page2 == nil) {         

           self.page2 = [[UIImageView alloc] initWithFrame:CGRectMake(320.0f, 0.0f,            

           self.view.frame.size.width, self.view.frame.size.height)];         

           self.page2.image = [UIImage imageNamed:@"罗丹-思想者.png"];         
           [self.scrollView addSubview:self.page2];    
           }          
           if (nextPage == 2 && self.page3 == nil) {         

           self.page3 = [[UIImageView alloc] initWithFrame:CGRectMake(2 * 320.0f, 0.0f,             

           self.view.frame.size.width, self.view.frame.size.height)];         

           self.page3.image = [UIImage imageNamed:@"保罗克利-肖像.png"];         
           [self.scrollView addSubview:self.page3];     
           }     
           }  
           @end 

           我们重新修改了这个实例,在viewDidLoad方法中只加载第一张图片,见第①行代码。如果用户滑动屏幕或点 击分屏控件进入第二个屏幕,则调用loadImage:方法加载第二张图片,类似地,如果要进入第三个屏幕,则调用 loadImage:方法加载第三张图片。 
      
           在这两种实现方式中,LazyLoadPageControlNavigation实现了延迟加载。很显然,LazyLoadPageControlNavigation 的延迟加载友好很多。那么,两者究竟有多大的差别,这是可以量化的。通过Instruments工具的Allocations模板,可 以分析ViewController视图控制器加载时内存占用方面的差别。图2是无延迟加载实现案例的Allocations模板跟 踪,图3是采用延迟加载实现案例的Allocations模板跟踪。 


    图2 无延迟加载实现案例的Allocations模板跟踪 

    图3 使用延迟加载实现案例的Allocations模板跟踪

           如图2所示,界面启动用时,内存占用马上达到8.12MB。如图3所示,界面启动用时,内存占用3.08MB, 当我们滑动到第二和第三屏幕时,内存占用达到8.06MB,内存变化会有明显的两个阶梯。 

           综上所述,延迟加载的优势很明显。如果一定会访问到资源文件,则延迟加载这些资源文件时,内存占用方面就没有优势了,但是在界面加载速度方面还是有优势的。 
           以上便是南昌APP开发公司-百恒网络为大家介绍的关于资源文件的延迟加载方法,希望对大家有所帮助!此外,如有需要APP开发、网站建设、微信开发等方面的服务的朋友,欢迎来电和我们联系,百恒随时为您服务!
    展开分享
    服务
    案例
    首页
    动态
    联系
    咨询