1.主要的逻辑:
while(传过来的参数model参数 ){
while(model){
handleRunloopStaus();//runloop的状态处理,是否stop
confidencegPort();//用于配制prot通信
timeRunloopTimeoutResume();//启动超时定时器,一般都不会超时,runloop设置超时
的时间很大。
runloopDoObservers(); //处理监听状态
runloopDoSourese();//处理Sources
if(msg){
goto;handle_msg; //处理消息(系统)
}
wait();等待消息
if(msg){
goto;handle_msg; //处理消息(系统)
}else{
__CFRunloopDoSourse();//处理sours
}
}
model --- 这里的model指的是runloop的两种模式kCFRunLoopDefaultMode和UITrackingRunLoopMode,第一个model的模式APP的默认Model,通常主线程是在这个Model下运行,而界面跟踪Model,用于Scrollview追踪触摸滑动,保证界面滑动时不受其他Model影响。
重点在于:runloop会通知监听者,需要处理事情了,包括他的时间与对象,然后利用block回掉,等待处理结果sourese为0,如果发现其他事情还需要处理,继续处理,如果没有告知监听者,runloop准备休息,睡觉。
2.自动释放池在什么时候会启动
自动释放池在Runloop发送通知的时候,就会自动的启动。
3.在什么情况下使用Runloop
// NSTimer defalultModel // tableview 在滑动的时候,不会被触发
// 常驻线程 runloop
// 自己创建线程, 处理一些延时操作,也需要用runloop
// 休眠的状态能监听到,利用这个状态处理事情
4.线程与NSRunloop的关系
每条线程都有唯一的一个与之对应的RunLoop对象。
主线程的RunLoop已经自动创建好了,子线程的RunLoop需要主动创建。
RunLoop在第一次获取时创建,在线程结束时销毁。
其实在创建线程的时候,并不是就创建了一个Runloop,需要自己去开启一个Runloop,需要调用这个方法:[[NSRunLoop currentRunLoop] run];// 开启一个Runloop与线程相对应,具体的源码:
// 如果__CFRunLoops 这个字典为nil,生成一个
if (!__CFRunLoops) {
__CFUnlock(&loopsLock);
CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
CFRunLoopRef mainLoop = __CFRunLoopCreate(pthread_main_thread_np());
// main线程和他的runloop关系对应起来 key是线程,value是runloop
CFDictionarySetValue(dict, pthreadPointer(pthread_main_thread_np()), mainLoop);
if (!OSAtomicCompareAndSwapPtrBarrier(NULL, dict, (void * volatile *)&__CFRunLoops)) {
CFRelease(dict);
}
CFRelease(mainLoop);
__CFLock(&loopsLock);
}
// 根据线程 获取runloop
CFRunLoopRef loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t));
__CFUnlock(&loopsLock);
// runloop 为空
if (!loop) {
// 创建了一个runloop
CFRunLoopRef newLoop = __CFRunLoopCreate(t);
__CFLock(&loopsLock);
// 再次获取一次
loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t));
if (!loop) {
// 关联起来
CFDictionarySetValue(__CFRunLoops, pthreadPointer(t), newLoop);
loop = newLoop;
}
// don't release run loops inside the loopsLock, because CFRunLoopDeallocate may end up taking it
__CFUnlock(&loopsLock);
CFRelease(newLoop);
}