runloop伪代码,切换mode是do循环里面做的,切换mode并不会导致外循环的结果发生变化,而来到return 0.所以切换mode,不会导致程序退出
如果图中的return 0 ,程序一启动后就会退出。主线程的runloop默认开启,是因为在UIApplicationMain里面获取过主线程的runloop
拿到当前的runloop对象,一个是oc的,一个是c语言的。NS开头的都是对CF开头的一种包装。就是说NSRunLoop是对CFRunLoopRef的一层oc包装
runloop和线程的关系
当前线程就是主线程,所以currentRunLoop跟mainRunLoop地址是一样的
获取当前线程runLoop的源码
核心方法:CFDictionaryGetValue(左边__CFRunLoops是一个字典,右边是一个key(pthread是一个线程,也就是线程是一个key)。传入一个字典,一个key,就可以获取到value)
第一次获取runloop为空的时候,就会去去创建一个runloop
数组可以有序取值,set只能随机取
runloop里面有一堆的mode,但是只有其中一个mode,可以称为当前mode。也就是很多模式里面,只采取一个模式来使用。_modes里面装的是CFRunLoopModeRef这种对象。mode里面有个名字,_sources0和_sources1装的是CFRunLoopSourceRef这种对象。_observers装是CFRunLoopObserverRef这种对象。_timers装的是CFRunLoopTimerRef这种对象。_pthread是线程对象, 每个runloop内部会保存它对应的线程,也就是runloop跟线程保持一对一的关系
同一时间只能运行一个mode,切换mode,不会导致程序退出。runloop在某种模式下运行的话,就是拿出对应
mode里面的source0,source1,obdervers,timers 进行处理
可以理解为NSRunLoop里面包含了CFRunLoop
runloop真正的地址是c语言打印的地址
bt打印函数调用栈,c语言函数里面只要是带了create和copy的,都需要进行realse
bt打印函数调用栈
这行代码不是一执行就立即生效的,一执行这行代码的话,会先记着有这么一个事情,observers监听到runloop即将睡觉了,它会在runloop睡觉之前,在我们这个线程睡觉之前,线程没什么事情做,就会睡觉,会在睡觉之前区刷新UI,也就是睡觉之前把view设置为红色
runloop有这几种状态
监听runloop,runloop切换状态的时候,就会调用我们的监听方法
程序一进来不会先打印默认的mode。因为runloop早就进入了默认的mode了,所以这个时候监听已经晚了,除非在程序一启动的时候就监听。开始滚动的时候,会先退出当前的默认mode,然后进入UITrackingRunLoopMode。手一松开(也就是停止滚动),就会退出UITrackingRunLoopMode,进入默认的mode。
定时器runloop相关
网友评论