天天看點

iOS多線程程式設計(四)NSRunLoop初步概念以及NSTimer在NSThread中的使用

1.NSRunloop基本概念

@Run loops 是線程相關的基礎架構的一部分.一個run loop就是一個事件處理的循環,用來不停的排程工作以及處理輸入事件.

@線程的生命周期存在五個狀态:建立,就緒,運作,阻塞,死亡

@NSRunLoop可以保持一個線程一直為活動狀态,不會馬上被銷毀掉,在多線程中,子線程就不會被銷毀

2.NSRunloop常用方法

+ (NSRunLoop *)currentRunLoop; //獲得目前線程的run loop

+ (NSRunLoop *)mainRunLoop; //獲得主線程的run loop

- (void)run; //進入處理事件循環,如果沒有事件則立刻傳回。注意:主線程上調用這個方法會導緻無法傳回(進入無限循環,雖然不會阻塞主線程),因為主線程一般總是會有事件處理。

- (void)runUntilDate:(NSDate *)limitDate; //同run方法,增加逾時參數limitDate,避免進入無限循環。使用在UI線程(亦即主線程)上,可以達到暫停的效果。

- (BOOL)runMode:(NSString *)mode beforeDate:(NSDate *)limitDate; //等待消息處理,好比在PC終端視窗上等待鍵盤輸入。一旦有合适事件(mode相當于定義了事件的類型)被處理了,則立刻傳回;類同run方法,如果沒有事件處理也立刻傳回;有否事件處理由傳回布爾值判斷。同樣limitDate為逾時參數。

- (void)acceptInputForMode:(NSString *)mode beforeDate:(NSDate *)limitDate; //似乎和runMode:差不多(測試過是這種結果,但确定是否有其它特殊情況下的不同),沒有BOOL傳回值。

官網文檔也提到run和runUntilDate:會以NSDefaultRunLoopMode參數調用runMode:來處理事件。

當程式運作後,主線程自動啟動一個run loop,而多線程則需要手動來啟動run loop。

3.定時器在多線程中的使用

@在多線程中使用定時器必須手動開啟Runloop

@代碼示例:

    [NSThread detachNewThreadSelector:@selector(onclick) toTarget:self withObject:nil];

- (void)onclick{

    // 子線程,需要手動加入一個釋放池,來釋放通過便利構造器建立的對象,主線程自動添加了

    @autoreleasepool {

        [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(ontime) userInfo:nil repeats:YES];

        // 開啟Runloop來使線程保持存活狀态

        [[NSRunLoop currentRunLoop] run];

    }

}

4.調用主線程的run loop的各種方式

[[NSRunLoop mainRunLoop] run]; //主線程永遠等待,但讓出主線程時間片

[[NSRunLoop mainRunLoop] runUntilDate:[NSDate distantFuture]]; //等同上面調用

[[NSRunLoop mainRunLoop] runUntilDate:[NSDate date]]; //立即傳回

[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10.0]]; //主線程等待,但讓出主線程時間片,然後過10秒後傳回

[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate: [NSDate distantFuture]]; //主線程等待,但讓出主線程時間片;有事件到達就傳回,比如點選UI等。

[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate: [NSDate date]]; //立即傳回

[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate: [NSDate dateWithTimeIntervalSinceNow:10.0]]; //主線程等待,但讓出主線程時間片;有事件到達就傳回,如果沒有則過10秒傳回。

繼續閱讀