使用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,所以問題就解決了。
相關文章
相關標籤/搜索