RunLoop

一、RunLoop概念

RunLoop是經過內部維護的事件循環來對事件/消息進行管理的一個對象數據結構

  • 沒有消息須要處理時,休眠以免資源佔用(用戶態 -> 內核態)
  • 有消息須要處理時,當即被喚醒(內核態 -> 用戶態)

二、數據結構

NSRunLoop是CFRunLoop的封裝,提供了面向對象的API多線程

  • CFRunLoop
  • CFRunLoopMode
  • Source/Timer/Observer

CFRunLoopSource
  • source0 須要手動喚醒線程
  • source1 具有喚醒線程的能力
CFRunLoopTimer

基於事件的定時器oop

CFRunLoopOberver

觀測時間點ui

  • kCFRunLoopEntery
  • kCFRunLoopBeforeTimer
  • kCFRunLoopBeforeSources
  • kCFRunLoopBeforeWaiting
  • kCFRunLoopAfterWaiting
  • kCFRunLoopExit

NSRunLoopCommonModesspa

  • CommonMode不是實際存在的Mode
  • 是同步Source/Timer/Observer到多個Mode中的一種技術方案

三、事件循環機制

四、RunLoop與NSTimer

滑動TableView時RunLoop發生Mode切換,由kCFRunLoopDefaultMode切換爲UITrackingRunLoopMode,要確保Timer事件的正常運行,須要同時添加到兩種mode下線程

void CFRunLoopAddTimer(runLoop, timer. commonMode) 複製代碼

五、RunLoop與多線程

線程與RunLoop一一對應; 本身建立的線程默認是沒有RunLoop的3d

如何實現常駐線程?
  • 當前線程開啓RunLoop
  • 向RunLoop添加Port/Source等維持RunLoop的事件循環
  • 啓動RunLoop
+ (NSThread *)_networkThread 
{
    static NSThread *thread = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        thread = [[NSThread alloc] initWithTarget:self, selector:@selctor(_networkThreadMain:) object:nil];
        if ([thread respondsToSelector:@selector(setQualityService:)]) {
            thread.qualityOfService = NSQualityServiceBackground;
        }
        [thread start];
    })
}

+ (void)_networkThreadMain:(id)object 
{
    @autoreleasePool {
        [[NSThread currentThread] setName:@"threadMain"];
        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
        [runLoop addPort:[NSMatchPort port] forMode:NSDefaultRunLoopMode];
        [runLoop run];
    }
}
複製代碼
相關文章
相關標籤/搜索