RunLoop

2017-12-01  本文已影响0人  松n_n鼠

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

#  Foundation

NSRunLoop

#  Core Foundation

CFRunLoopRef

//    NSRunLoop和CFRunLoopRef都代表着RunLoop对象

//    NSRunLoop是基于CFRunLoopRef的一层OC包装,所以要了解RunLoop内部结构,需要多研究CFRunLoopRef层面的API(Core Foundation层面)

RunLoop资料

苹果官方文档:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html

CFRunLoopRef(开源)
http://opensource.apple.com/source/CF/CF-1151.16/

RunLoop与线程

每条线程都有唯一的一个与之对应的RunLoop对象,主线程的RunLoop已经自动创建好了,子线程的RunLoop需要主动创建,RunLoop在第一次获取的时候创建,在线程结束的时候销毁。

获取RunLoop对象

//    Foundation
[NSRunLoop currentRunLoop];  //  获得当前线程的RunLoop对象
[NSRunLoop mainRunLoop];  //  获得主线程的RunLoop对象

//    Core Foundation
CFRunLoopGetCurrent();  //  获得当前线程的RunLoop对象
CFRunLoopGetMain();  //  获得主线程的RunLoop对象 

Core Foundation中关于RunLoop的5个类

CFRunLoopRef:它自己,也就代表一个RunLoop对象
CFRunLoopModeRef :RunLoop的运行模式
     一个 RunLoop 包含若干个 Mode,每个Mode又包含若干个Source/Timer/Observer每次RunLoop启动时,只能指定其中一个Mode,这个Mode被称作 CurrentMode如果需要切换Mode,只能退出Loop,再重新指定一个Mode进入这样做主要是为了分隔开不同组的Source/Timer/Observer,让其互不影响
     kCFRunLoopDefaultMode:App的默认Mode,通常主线程是在这个Mode下运行
     UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响
     UIInitializationRunLoopMode: 在刚启动 App 时进入的第一个 Mode,启动完成后就不再使用
     GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到
     kCFRunLoopCommonModes: 这是一个占位用的Mode,不是一种真正的Mode
     被标记为common modes模式kCFRunLoopDefaultMode UITrackingRunLoopMode两种模式

CFRunLoopSourceRef :事件源
     以前的分法
     Port-Based Sources
     Custom Input Sources
     Cocoa Perform Selector Sources
     现在的分法
     Source0:非基于Port的
     Source1:基于Port的
CFRunLoopTimerRef :时间的触发器
     CFRunLoopTimerRef是基于时间的触发器,基本上就是NSTimer
CFRunLoopObserverRef :观察者 监听CFRunLoopRef的状态改变
     观察者,能够监听RunLoop状态改变。
         /* Run Loop Observer Activities */
        typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
        kCFRunLoopEntry = (1UL << 0),  //即将进入Loop
        kCFRunLoopBeforeTimers = (1UL << 1),  //  即将处理Timer
        kCFRunLoopBeforeSources = (1UL << 2), //  即将处理Sources
        kCFRunLoopBeforeWaiting = (1UL << 5), //即将进入休眠
        kCFRunLoopAfterWaiting = (1UL << 6), // 刚从休眠中唤醒
        kCFRunLoopExit = (1UL << 7), //  即将退出Loop
    };
上一篇下一篇

猜你喜欢

热点阅读