使用runloop阻塞線程的正確寫法

使用runloop阻塞線程的正確寫法

http://marshal.easymorse.com/archives/4700

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,因此問題就解決了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章