RunLoop详解

2017-05-23  本文已影响108人  伶俐ll

RunLoop简介

RunLoop与线程的关系

RunLoop相关API

iOS中有2套API来访问和使用RunLoop,

RunLoop相关类

Core Foundation中提供了关于RunLoop的5个类

image.png 屏幕快照 2018-07-18 下午3.18.24.png
CFRunLoopModeRef
CFRunLoopSourceRef

事件源(输入源)
在 iOS 中有两种分类方法,按照以前的分类方法可以分为:①基于端口的;②自定义的;③performSelector事件;
按照函数调用栈来划分,可以分为source0和soucr1。

CFRunLoopTimerRef
   + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;
   + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo
   + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block ;

创建 timer,需要手动把 timer 添加到 RunLoop 中,可以指定添加到哪种模式下。
2、 scheduledTimerWithXXX

    + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;
    + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block ;
    + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;

这种方法除了创建一个定时器外会自动以NSDefaultRunLoopModeMode添加到当前线程RunLoop中,但是如果滚动UIScrollView(UITableView、UICollectionview等类似的)是无法正常工作的,但是如果将NSDefaultRunLoopMode改为NSRunLoopCommonModes则可以正常工作。

注意:

CFRunLoopObserverRef

相当于消息循环中的一个监听器,随时通知外部当前RunLoop的运行状态(它包含一个函数指针callout将当前状态及时告诉观察者)。具体的Observer状态如下

         kCFRunLoopEntry = (1UL << 0),        即将进入runloop
         kCFRunLoopBeforeTimers = (1UL << 1), 即将处理timer事件
         kCFRunLoopBeforeSources = (1UL << 2),即将处理source事件
         kCFRunLoopBeforeWaiting = (1UL << 5),即将进入睡眠,一般在这个状态进行UI界面的刷新和对自动释放池进行release操作
         kCFRunLoopAfterWaiting = (1UL << 6), 被唤醒
         kCFRunLoopExit = (1UL << 7),         runloop退出
         kCFRunLoopAllActivities = 0x0FFFFFFFU

和定时器类似,runLoop 观察者可以只用一次或循环使用。若只用一次,那么在 它启动后,会把它自己从 runLoop 里面移除,而循环的观察者则不会。你在创建 runLoop 观察者的时候需要指定它是运行一次还是多次。

Run Loop 的运行逻辑

屏幕快照 2018-07-18 下午3.33.50.png

RunLoop休眠的实现原理

屏幕快照 2018-07-18 下午3.39.58.png

在开发中如何使用RunLoop?什么应用场景?

自动释放池与RunLoop

kCFRunLoopEntry; // 当runloop进入的时候会创建一个自动释放
kCFRunLoopBeforeWaiting; // 当runloop即将进入休眠的时候会把之前的自动释放池先销毁,然后创建一个新的自动释放池。
kCFRunLoopExit; // 当runloop退出的时候会把之前的自动释放池销毁。
上一篇 下一篇

猜你喜欢

热点阅读