RunLoop,跑圈。在iOS开发中,也就是运行循环。



在应用需要的时候自己跑起来运行,在用户没有操作的时候就停下来休息。充分节省CPU资源,提高程序性能。

 

. RunLoop的概念与作用



概念:一般来讲,一个线程一次只能执行一个任务,执行完成后线程就会退出。但是有时候我们需要线程能够一直“待命”随时处理事件而不退出,这就需要一个机制来完成这样的任务。



例如一个应用放那里,不进行操作就像静止休息一样,点击按钮,就有响应,就像“随时待命”一样,这就是RunLoop的功劳。



所以RunLoop 实际上就是一个对象,这个对象管理了其需要处理的事件和消息,并提供了一个入口函数来执行RunLoop 的逻辑。 

线程开始这个函数之后,便一直会处于此函数 "接受消息->等待->处理" 的循环中:(有事:做出反应;   木事:休眠省电;   再次有事:重新唤醒、处理事件。)

直到这个循环结束(比如传入 quit 的消息),最后函数返回。

作用:

  1. 保持程序持续运行:例如程序一启动就会开一个主线程,主线程一开起来就会跑一个主线程对应的RunLoop,RunLoop保证主线程不会被销毁,也就保证了程序的持续运行;
  2. 处理App中的各种事件(比如:触摸事件,定时器事件,Selector事件等 );
  3. 节省CPU资源,优化程序性能:程序运行起来时,当什么操作都没有做的时候,RunLoop就通知系统,现在没有事情做,然后进行休息待命状态,这时系统就会将其资源释放出来去做其他的事情。当有事情做,也就是一有响应的时候RunLoop就会立马起来去做事情;

RunLoop,最重要的作用,也就是用来管理线程的。可以说,没有线程,也就没有RunLoop的存在必要。

当线程的RunLoop一开启,RunLoop便开始对线程进行管理工作:在线程执行完任务后,线程便会进入休眠状态,并且不会退出,随时等待新的任务。

 

三、RunLoop与线程的关系

1.每条线程都有唯一的一个与之对应的RunLoop对象;

2.RunLoop在第一次获取时创建,在线程结束时销毁;只能在一个线程的内部获取其 RunLoop(主线程除外)。

3.主线程的RunLoop系统默认启动,子线程的RunLoop需要主动开启;



其实在我们每次建立项目的时候,就已经使用上了RunLoop。



 



 



(这里只是粗略的知识点,主要的看下面截图)



 



只有主线程的消息循环默认开启,子线程的消息循环默认不开启



 



(个人理解) 每一个输入源或定时源都必须对应一个模式(只有与消息循环的模式对应上了,,这里的定时源才会执行)



 



    消息循环是在一个指定的模式下运行的 默认的模式NSDefaultRunLoopMode,设置的输入事件也需要指定一个模式,消息循环的模式必须和输入事件的模式匹配才会执行



 



UITrackingRunLoopMode  当滚动scrollView的时候,消息循环的模式会改变成这种



 



 



使用消息循环的时候必须指定两件事情



    



    1 .   输入事件:输入源和定时源



      2 .   消息循环的模式



 



eg:



 



//  这里的self,是selector里面的方法的所属对象 
  
//  userInfo 是方法跟的参数 
  
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(demo) userInfo:nil repeats:YES]; 
  
    
  
//把定时器添加到当前线程消息循环中                        这个就是定时源的模式 
  
 

   [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode]; 
  
 
 
 
  currentRunLoop  当前的消息循环吧 
 
 
 

     
 
 
 

   *********** 
 
 
 

   - (void)demo { 
 
 
 

       //输出当前消息循环的模式 
  
    NSLog(@"%@",[NSRunLoop currentRunLoop].currentMode); 
  
 } 
  
 

     
 
 
 

     
 
 
 
 
  
 #import "ViewController.h" 
  

 @interface ViewController () 
  

 @end 
  

 @implementation ViewController 
  

 - (void)viewDidLoad { 
  
    [super viewDidLoad]; 
  
    
  
    //  这里的self,是selector里面的方法的所属对象 
  
    //  userInfo 是方法跟的参数 
  
    NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(demo) userInfo:nil repeats:YES]; 
  
    
  
    //把定时器添加到当前线程消息循环中                        这个就是定时源的模式 
  
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode]; 
  

    // (个人理解) 每一个输入源或定时源都必须对应一个模式(只有与消息循环的模式对应上了,,这里的定时源才会执行) 
  
    //消息循环是在一个指定的模式下运行的 默认的模式NSDefaultRunLoopMode,设置的输入事件也需要指定一个模式,消息循环的模式必须和输入事件的模式匹配才会执行 
  

    //UITrackingRunLoopMode  当滚动scrollView的时候,消息循环的模式会改变成这种 
  
 } 
  

 - (void)demo { 
  
    //输出当前消息循环的模式 
  
    NSLog(@"hello %@",[NSRunLoop currentRunLoop].currentMode); 
  
 } 
  

 @end