Runloop源码解析

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);

}

你可能感兴趣的:(Runloop源码解析)