但某些时候,我们希望让主线程等待IO操作完成——例如主线程创建了一个文件夹后,等待完成,再往文件夹中创建文件。
1、使用时,先利用函数CFRunLoopSourceSignal(source)进行标记,然后再通过 CFRunLoopWakeUp(runloop) 来唤醒线程,去执行 source1 包含了mach_port和回调。
2、有两个version的source:source0,source source0:处理app内部事件,app自己负责管理(触发)。如UIEvent,CFSocket。 source1:由RunLoop和系统内核管理,mach port驱动,如CFPort,CFMessagePort。
3、当 RunLoop 运行在 Mode1 上时,是无法接受处理 Mode2 或 Mode3 上的 Source、Timer、Observer 事件的。
4、Mode中包含的item sources0、sources1 machport timer observers mode中至少有一个存在RunLoop才不会退出。
5、RunLoop 会在之一次获取时创建,在线程结束时销毁。
6、将触摸事件交给前台app进程来处理。 参考: RunLoop原理学习 - APP响应阶段 APP进程的mach port 接收到 SpringBoard 进程传递来的触摸事件,主线程的 runloop被唤醒,触发了source1回调。
iOS中的延迟执行,一般有三种 *** :performSelector、NSTimer、dispatch_after *** 一:这里需要注意参数需要保持一致,否则取消失败。
这里需要补充的知识: 关于performSelector调用和直接调用 *** 的区别 performSelector是运行时系统负责去找 *** 的,在编译时候不做任何校验;如果直接调用编译是会自动校验。
在有多线程操作的环境中,这样performSelector的延时调用,其实是缺乏安全性的。
performSelector是运行时系统负责去找 *** ,在编译时不会对调用的 *** 做检查,只有在运行的时候才会检查,如果 *** 存在就调用,如果放不存在就不会调用。
NSObject类有一个 *** performSelectorOnMainThread:withObject:waitUntilDone可以让主线程挂起,但selector至多只能带一个可传参数,这时需要用到NSInvocation类来解决这个问题。