在ios開發多線程程序的時候,往往會碰到run loop。
對於run loop, 蘋果開發網站上有非常詳細的說明,www.2cto.com
強烈建議啃下來,不要怕英文。
copy了一下圖片:
這裡就寫個Timer sources的簡單例子。
系統創建一個線程的時候,就已經默認創建了一個run loop了,除了主線程默認run loop就是運行的,其他的輔助線程雖說已經創建了run loop但是並沒有運行。
獲取線程的run loop對象
NSRunLoop* loop = [NSRunLoop currentRunLoop];通過上面簡單的代碼就可以獲取當前線程的run loop對象。
創建一個定時器
// Creates and returns a new NSTimer object and schedules it on the current run loop in the default mode [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(doFireTimer:) userInfo:nil repeats:YES];doFireTimer每0.1秒會被調用一次。簡單如下:
- (void) doFireTimer:(NSTimer *)timer { NSLog(@doFireTimer, %f, timer.timeInterval); }
NSInteger loopCount = 2; do { // 啟動當前thread的run loop直到所指定的時間到達,在run loop運行時,run loop會處理所有來自與該run loop聯系的input sources的數據 // 對於本例與當前run loop聯系的input source只有Timer類型的source // 該Timer每隔0.1秒發送觸發時間給run loop,run loop檢測到該事件時會調用相應的處理方法(doFireTimer:) // 由於在run loop添加了observer,且設置observer對所有的run loop行為感興趣 // 當調用runUntilDate方法時,observer檢測到run loop啟動並進入循環,observer會調用其回調函數,第二個參數所傳遞的行為時kCFRunLoopEntry // observer檢測到run loop的其他行為並調用回調函數的操作與上面的描述相類似 [loop runUntilDate:[NSDate dateWithTimeIntervalSinceNow: 0.2]]; // 當run loop的運行時間到達時,會退出當前的run loop,observer同樣會檢測到run loop的退出行為,並調用其回調函數,第二個參數傳遞的行為是kCFRunLoopExit. --loopCount; }while(loopCount);
因為定時器每隔0.1秒發送一個消息,這樣每次runUntilDate應該會接受到2次消息。(把0.2改成0.21啥的,應該就是2次,0.2的話還不一定,因為當發送第二次定時器的時候,run loop生命周期也剛剛到,可能第二次不一定能被處理)。
大致的流程就是
1. 定時器發送消息,每隔0.1秒
2. run loop收到消息,調用doFireTimer函數。
運行如下:可以從左邊的調用棧裡面看到doFireTimer是從run loop裡面調用的。
完整代碼如下:只要在主線程裡面啟動這個線程就可以了。
[NSThread detachNewThreadSelector:@selector(MyThread) toTarget:self withObject:nil];
- (void) doFireTimer:(NSTimer *)timer { NSLog(@doFireTimer, %f, timer.timeInterval); } - (void) MyThread { NSRunLoop* loop = [NSRunLoop currentRunLoop]; // Creates and returns a new NSTimer object and schedules it on the current run loop in the default mode [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(doFireTimer:) userInfo:nil repeats:YES]; NSInteger loopCount = 2; do { // 啟動當前thread的run loop直到所指定的時間到達,在run loop運行時,run loop會處理所有來自與該run loop聯系的input sources的數據 // 對於本例與當前run loop聯系的input source只有Timer類型的source // 該Timer每隔0.1秒發送觸發時間給run loop,run loop檢測到該事件時會調用相應的處理方法(doFireTimer:) // 由於在run loop添加了observer,且設置observer對所有的run loop行為感興趣 // 當調用runUntilDate方法時,observer檢測到run loop啟動並進入循環,observer會調用其回調函數,第二個參數所傳遞的行為時kCFRunLoopEntry // observer檢測到run loop的其他行為並調用回調函數的操作與上面的描述相類似 [loop runUntilDate:[NSDate dateWithTimeIntervalSinceNow: 0.2]]; // 當run loop的運行時間到達時,會退出當前的run loop,observer同樣會檢測到run loop的退出行為,並調用其回調函數,第二個參數傳遞的行為是kCFRunLoopExit. --loopCount; }while(loopCount); }