面试iOS学习程序员

iOS NSTimer和RunLoop问题

2017-09-30  本文已影响269人  迷恋代码

1.浅谈RunLoop

runLoop从字面的意思上看是运行中的循环,作用是保持APP的持续运行,处理APP的各种事件,比如点击事件、定时器事件、Selector事件,节省CPU资源,提高APP的性能,能够让线程在有工作的时候忙碌,在没有工作的时候休眠


2.RunLoop和线程的关系

1.runLoop和线程是紧密关联的,可以说是为了线程而生,没有线程,runLoop也没存在的必要。

2.runLoop和线程是一一对应的,主线程的runLoop默认是创建的,子线程的需要手动创建。currentRunLoop懒加载的,在同一个子线程中创建多个runloop,则返回的都是同一个对象,因为其是懒加载模式的

      获得主线程的runLoop:NSRunLoop *mainRunLoop =[NSRunLoop mainRunLoop];

      获得当前线程runLoop:NSRunLoop *currentRunLoop =[NSRunLoop currentRunLoop];

3.在runloop中有多个运行模式,但是runloop只能选择一种模式运行,mode里面至少要有一个timer或者是source

4.在第一次获取时创建,在线程结束时销毁


3.RunLoop的几个类

1.CFRunLoopRef:NSRunLoop对象是OC对象,是对CFRunLoopRef的封装,可以通过getCFRunLoop方法获取其对应的CFRunLoopRef对象。注意,NSRunLoop不是线程安全的,但CFRunLoopRef是线程安全的

2.RunLoopMode:NSRunLoop对象是一系列RunLoopMode的集合,每个mode包括有这个模式下所有的Source源、Timer源和观察者。每次RunLoop调用的时候都只能调用其中的一个mode,接收这个mode下的源,通知这个mode下的观察者。这样设计的主要目的就是为了隔离各个模式下的源和观察者,使其不相互影响,常用的五种模式:

 kCFRunLoopDefaultMode:App默认的mode,一般情况下App都是运行在这个mode  下的

 UITrackingRunLoopMode:界面跟踪时的mode,一般用于ScrollView滚动的时候追 踪的,保证滑动的时候不受其他事件影响

UIInitializationRunLoopMode:在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用

GSEventReceiveRunLoopMode:接受系统事件的内部 Mode,一般用不到

kCFRunLoopCommonModes:占位mode,可以向其中添加其他mode用以检测多个mode的事件

3.CFRunLoopSourceRef:事件源产生的地方

4.CFRunLoopTimerRef:是基于事件的触发器,其中包含一段时间长度、延期容忍度和一个函数指针(回调方法)。当其加入到RunLoop中时,RunLoop会注册一个时间点,当到达这个时间点后,会触发对应的事件。

5.CFRunLoopObserverRef:RunLoop的观察者。每个观察者都可以观察RunLoop在某个模式下事件的触发并处理

kCFRunLoopEntry:即将进入runLoop

kCFRunLoopBeforeTimers:即将处理Timer

kCFRunLoopBeforeSources:即将处理Source

kCFRunLoopBeforeWaiting:即将进入休眠

kCFRunLoopAfterWaiting:刚从休眠中被唤醒

kCFRunLoopExit:即将退出RunLoop


4.NSTimer在RunLoop中的使用

方式一:

图1

方式二:

图2

5.RunLoop常驻线程

注意事项:当进入block的时候,先创建了timer,并且也把timer也把timer加入到runloop中,但是很重要的一点子线程中Runloop不会自动运行,需要手动运行,因为这里没有运行Runloop,所以timer就被释放掉了,所以导致了啥都没有。

小知识:[[NSRunLoop currentRunLoop] run],运行runloop,

[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];指定runloop在指定模式下,设置开始时间,开启成功会返回YES

[[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantFuture]];

运行runloop直到一个时间

上一篇下一篇

猜你喜欢

热点阅读