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