美文网首页
Hi,runloop 交个朋友吧

Hi,runloop 交个朋友吧

作者: 眯大帅 | 来源:发表于2016-07-04 09:49 被阅读46次

developer:hi,runloop 初次见面,交个朋友吧?
runloop :你好,很高兴认识你!

developer:我先自我介绍一下,我叫iOS Developer,你呢?
runloop :我叫runloop,你的有些同伴叫我跑圈,我觉得叫我循环运行比较合适!

developer:我听我的同伴说你有点不是很好相处啊,是不是真的?
runloop :不会吧,我只是喜欢在幕后工作,并不是很爱抛头露面而已!

developer:那你的主要工作内容都是哪些呢?
runloop :我啊?主要是为了让程序一直处于运行状态,同时在运行的状态下处理一系列的事件,比如触摸事件定时器事件selecter事件,在这样的高强度的工作下还得维持良好的状态!

developer:听起来很屌的样子!跟我说说你跟线程的关系吧,听说你两是生死相依的兄弟!
runloop :线程啊,我两谁也离不开谁,他出生了我也就诞生了,当他被销毁的时候我也就扑街了。

developer:那平时我们拜访线程挺容易的,要怎么去拜访你呢?
runloop :有两种方式
1、Foundation框架下的NSRunLoop
2、Core Foundation框架下得CFRunLoopRef
不论NSRunLoop和CFRunLoopRef都代表着我

[NSRunLoop currentRunLoop]; // 获得当前线程的RunLoop对象
[NSRunLoop mainRunLoop]; // 获得主线程的RunLoop对象
CFRunLoopGetCurrent(); // 获得当前线程的RunLoop对象
CFRunLoopGetMain(); // 获得主线程的RunLoop对象
相关类
看到这张图没?
这张图就代表着一个完整的runloop,每一个runloop中都包含以下5个类:
CFRunLoopRef
CFRunLoopModeRef
CFRunLoopSourceRef
CFRunLoopTimerRef
CFRunLoopObserverRef
如果没有这5个类,runloop将会直接退出

developer:能详细的介绍以下他们吗?
runloop :当然。

CFRunLoopModeRef
CFRunLoopModeRef 类并没有对外暴露,只是通过 CFRunLoopRef 的接口进行了封装。
CFRunLoopModeRef代表RunLoop的运行模式

一个 RunLoop 包含若干个 Mode,每个 Mode 又包含若干个 Source/Timer/Observer。每次调用 RunLoop 的主函数时,只能指定其中一个 Mode,这个Mode被称作 CurrentMode。如果需要切换 Mode,只能退出 Loop,再重新指定一个 Mode 进入。这样做主要是为了分隔开不同组的 Source/Timer/Observer,让其互不影响。

系统默认注册了5个Mode:
kCFRunLoopDefaultMode:App的默认Mode,通常主线程是在这个Mode下运行
UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响
UIInitializationRunLoopMode: 在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用
GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到
kCFRunLoopCommonModes: 这是一个占位用的Mode,不是一种真正的Mode

CFRunLoopSourceRef
CFRunLoopSourceRef 是事件产生的地方。Source有两个版本:Source0 和 Source1。
• Source0 只包含了一个回调(函数指针),它并不能主动触发事件。使用时,你需要先调用 CFRunLoopSourceSignal(source),将这个 Source 标记为待处理,然后手动调用 CFRunLoopWakeUp(runloop) 来唤醒 RunLoop,让其处理这个事件。
• Source1 包含了一个 mach_port 和一个回调(函数指针),被用于通过内核和其他线程相互发送消息。

CFRunLoopObserverRef
CFRunLoopObserverRef 是观察者,每个 Observer 都包含了一个回调(函数指针),当 RunLoop 的状态发生变化时,观察者就能通过回调接受到这个变化。可以观测的时间点有以下几个:

typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
    kCFRunLoopEntry         = (1UL << 0), // 即将进入Loop
    kCFRunLoopBeforeTimers  = (1UL << 1), // 即将处理 Timer
    kCFRunLoopBeforeSources = (1UL << 2), // 即将处理 Source
    kCFRunLoopBeforeWaiting = (1UL << 5), // 即将进入休眠
    kCFRunLoopAfterWaiting  = (1UL << 6), // 刚从休眠中唤醒
    kCFRunLoopExit          = (1UL << 7), // 即将退出Loop
};

上面的 Source/Timer/Observer 被统称为 mode item,一个 item 可以被同时加入多个 mode。但一个 item 被重复加入同一个 mode 时是不会有效果的。如果一个 mode 中一个 item 都没有,则 RunLoop 会直接退出,不进入循环。

使用

- (void)observer{ 
// 创建observer CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) { 
NSLog(@"----监听到RunLoop状态发生改变---%zd", activity); 
}); 
// 添加观察者:监听RunLoop的状态 
CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode); 
// 释放Observer 
CFRelease(observer);}

特别注意

/* CF的内存管理(Core Foundation) 
1.凡是带有Create、Copy、Retain等字眼的函数,创建出来的对象,都需要在最后做一次release * 比如CFRunLoopObserverCreate 
2.release函数:CFRelease(对象); 
*/

CFRunLoopTimerRef
CFRunLoopTimerRef 是基于时间的触发器,它和 NSTimer 是toll-free bridged 的,可以混用。其包含一个时间长度和一个回调(函数指针)。当其加入到 RunLoop 时,RunLoop会注册对应的时间点,当时间点到时,RunLoop会被唤醒以执行那个回调。

RunLoop 的内部逻辑
根据苹果在文档里的说明,RunLoop 内部的逻辑大致如下:

RunLoop
可以看到,实际上 RunLoop 就是这样一个函数,其内部是一个 do-while 循环。当你调用 CFRunLoopRun() 时,线程就会一直停留在这个循环里;直到超时或被手动停止,该函数才会返回。

developer:那我应该怎么样劳烦你去处理一些问题呢?
runloop :解密-神秘的RunLoop这里有记录怎么去使用runloop

developer:如何才能与你深交呢?
runloop :深入理解RunLoop

相关文章

  • Hi,runloop 交个朋友吧

    developer:hi,runloop 初次见面,交个朋友吧?runloop:你好,很高兴认识你! develo...

  • Hi Guy,交个朋友吧

    这是简书的第一篇文章,也是日更挑战的第一篇文章。 2020年快结束的时候制定的2021年的目标,目标包罗万象,丰富...

  • 嗨,交个朋友朋友吗?

    Hi,交个朋友吗?带上故事

  • 交个朋友吧

    笔名:安南98年老阿姨一枚平时爱好写作 读文 瑜伽等一些轻运动最近比较偏爱养生 人生就应该尝试去过自己想要的生活,...

  • 交个朋友吧!

    其实对于一个很宅的我来说,确实不是很懂社交,更别提什么社交高手,一个手机,我能在宿舍里待一个星期,我想很多人里也有...

  • 交个朋友吧

    我是王大七 那些记忆已经远走,远走得就像没发生过一样 。 说它像梦,可它真真切切的存在过,那些歌依然很动听,...

  • 交个朋友吧

    姓名 肖小晓 爱好 网球,写作,读书,旅行 看过了世间变化,才懂得云淡风轻 茫茫人海中,遇见是一种缘分,希望能和...

  • 交个朋友吧

    犹豫了好久,觉得文学这条路还是希望有些志同道合的人,至少不那么孤独。 先自我介绍:大二工科,化学在学,本人很木讷,...

  • 交个朋友吧

    你好!不介意交个朋友吧,没有花里胡哨的东东,但愿与你成为笔友,平常可以相互聊聊,消磨些闲暇的时光......

  • 交个朋友吧

    人生有很多选择,或许不如意,但至少是回忆。 喜欢三五好友,一两座小屋,四个板凳,六七瓶啤酒,八卦一下人...

网友评论

      本文标题:Hi,runloop 交个朋友吧

      本文链接:https://www.haomeiwen.com/subject/bikfjttx.html