runloop能夠阻塞線程,等待其餘線程執行後再執行。
好比:
@implementation ViewController{
BOOL end;
}
…
– (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@」start new thread …」);
[NSThread detachNewThreadSelector:@selector(runOnNewThread) toTarget:self withObject:nil];
while (!end) {
NSLog(@」runloop…」);
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
NSLog(@」runloop end.」);
}
NSLog(@」ok.」);
}
-(void)runOnNewThread{
NSLog(@」run for new thread …」);
sleep(1);
end=YES;
NSLog(@」end.」);
}
可是這樣作,運行時會發現,while循環後執行的語句會在很長時間後才被執行。
那是否是能夠這樣:
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:
[NSDate dateWithTimeIntervalSinceNow:0.1]];
縮短runloop的休眠時間,看起來解決了上面出現的問題。
不過這樣也又問題,runloop對象被常常性的喚醒,這違背了runloop的設計初衷。runloop的做用就是要減小cpu作無謂的空轉,cpu可在空閒的時候休眠,以節約電量。
那麼怎麼作呢?正確的寫法是:
-(void)runOnNewThread{
NSLog(@」run for new thread …」);
sleep(1);
[self performSelectorOnMainThread:@selector(setEnd) withObject:nil waitUntilDone:NO];
NSLog(@」end.」);
}
-(void)setEnd{
end=YES;
}
見黑體斜體字部分,要將直接設置變量,改成向主線程發送消息,執行方法。問題獲得解決。
這裏要說一下,形成while循環後語句延緩執行的緣由是,runloop未被喚醒。由於,改變變量的值,runloop對象根本不知道。延緩的時長老是不定的,這是由於,有其餘事件在某個時點喚醒了主線程,這才結束了while循環。那麼,向主線程發送消息,將喚醒runloop,所以問題就解決了。