1)什么是 Runloop ?

、字面上是运行循环,内部就是 do-while 循环,在这个循环内不断地处理各种任务。

、一个线程对应一个,主线程的默认是开启的。子线程的需手动开启。

、RunLoop 只能对应选择一个启动,如果当期的中没有任何、Timmer,那么就直接退出。

、基本作用就是保持程序的持续运行,处理中的各种事件、通过,有事执行,没事休眠,可以节省资源,提高程序性能。

 

)iOS 中有2套访问和使用 RunLoop

在框架下:NSRunLoop

在Core Fundation 下:CFRunLoopRef

比较:

、NSRunLoop 和都代表对象

、NSRunLoop 是基于 CFRunLoopRef 的一层 OC 封装。

 

)RunLoop 与线程:

、每条线程都有唯一对应的对象;

、主线程的已经自动创建好了,子线程的需要主动创建

、RunLoop 在第一次获取时创建,在线程结束时销毁。

 

)获取对象:

框架:

获取当前线程的对象

获取主线程的对象

框架:

获取当前线程的对象

获取主线程的对象

 

)RunLoop 处理逻辑:

、通知:即将进入 Loop

、通知:即将处理 Timer

、通知:将要处理 Source0

、处理 Source0

、如果有,跳到步骤 9

、通知:线程即将休眠

、休眠,等待唤醒:

                    1> Source0(port)

启动

设置的已经超时

被外部手动唤醒

、通知:线程将被唤醒

、处理未处理的时间:

如果用户定义的定时器启动,处理定时器事件并重启。进入步骤 2

如果输入源启动,传递相应的消息

如果被显式唤醒而且时间还没超时,重启,进入步骤 2

、通知:即将推出 Loop

 

)RunLoop 应用场景:

            NSTimer

显示

            PerformSelector

常驻线程

自动释放池

 

应用场景:

开启一个常驻线程(让一个子线程不进入消亡状态,等待其他线程发来消息,处理其他事件)

在子线程中开启一个定时器

在子线程中进行一些长期监控

可以控制定时器在特定模式下执行

可以让某些事件(行为、任务)在特定模式下执行

可以添加监听的状态,比如监听点击事件的处理(在所有点击事件之前做一些事情)

 

)NSRunLoop 的实现机制,及在多线程中如何使用

程序创建子线程的时候,才需要手动启动,主线程的默认开启

在多线程中,你需要判断是否需要,如果需要,那么你负责配置并启动,你不需要在任何时候都去启动。例如:使用线程去处理一个预定好的耗时极长的任务时,你就可以无需启动。RunLoop 只有在和线程交互时才需要。

 

)RunLoop 的的作用:

主要用来指定事件在运行循环中的优先级的。

(kCFRunLoopDefaultMode):默认,空闲状态

:滑动时会切换到该Mode

:启动时,会切换到该 mode

 

如果我们把一个对象以(KCFRunLoopDefaultMOde)添加到主运行循环中的时候,ScrollView滚动过程中会因为的切换,而导致不在被调度。当我们滚动的时候,也不希望调度,那么就应该使用默认模式。但是,虚妄在滚动时,定时器也要回调,那就应该使用。

 

如果想要销毁,则必须先将置为失效,否则就一直占用内存而不会释放。造成逻辑上的内存泄露。该泄露不会使用工具检测出来、另外对于要求必须销毁的的逻辑处理,未将置为失效,若每次都创建一次,则之前的不能得到释放,则会同时存在多个的实例在内存中。

 

在不需要时,一定要调用方法使定时器失效,否则得不到释放。

 

如果要滚动过程中定时器正常回调,UI 正常刷新,那么要将放入下,因为只有在空闲状态下才会回调。

 

的滚动导致失效:

、更改为(无论运行在哪个都能运行)

、切换到主线程来更新界面刷新

将timer添加到中

[NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES];

然后再添加到里

NSTimer *timer = [NSTimer timerWithTimeInterval:2 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES];
                    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];