十三年专注于网站建设与互联网应用开发,低调、有情怀的网络应用服务商!
南昌百恒科技微信公众号 扫一扫关注
tel-icon全国服务热线:400-680-9298,0791-88117053
扫一扫关注百恒科技微信公众号

IOS开发之资源文件的延迟加载方法

百恒 2017-09-11 15:41:17 3330
       延迟加载指一些对象不是在应用和视图等初始化时创建,而是在用到它的时候创建。当应用中有一些对象并不经常使用时,延迟加载可以提高程序性能。  
       首先,我们要考虑的就是对资源文件的延迟加载。由于资源文件的访问涉及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开发、网站建设、微信开发等方面的服务的朋友,欢迎来电和我们联系,百恒随时为您服务!
400-680-9298,0791-88117053
扫一扫关注百恒网络微信公众号

欢迎您的光顾,我们将竭诚为您服务×

售前咨询 售前咨询
 
售前咨询 售前咨询
 
售前咨询 售前咨询
 
售前咨询 售前咨询
 
售前咨询 售前咨询
 
售后服务 售后服务
 
备案专线 备案专线
 
售后服务 售后服务
 
×