1、簡單的可以想到,寫一個while循環
while (TRUE) { }
但是這種方式存在缺陷,將導致CPU占用100%,兩個核。
這種方式不優雅,會導致循環空轉,占用大量CPU。即使在循環中加入sleep也不是特別好的方式。
2、在iOS中特有的方式,使用Runloop是否結束作為循環判斷條件
[NSTimer scheduledTimerWithTimeInterval:[[NSDate distantFuture] timeIntervalSinceNow] target:self selector:@selector(ignore:) userInfo:nil repeats:YES]; NSThread *currentThread = [NSThread currentThread]; NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop]; BOOL isCancelled = [currentThread isCancelled]; NSLog(@"hello 1"); while (!isCancelled && [currentRunLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) { NSLog(@"hello 2"); isCancelled = [currentThread isCancelled]; } NSLog(@"hello 3");
在創建的線程體中運行上面的代碼,將輸出:
2017-03-22 19:28:50.693824 NSThreadTest[3459:785928] hello 1
這個時候線程像是阻塞在while處,而是處於休眠狀態,當Runloop中有事件源的時候,線程會喚醒,並且執行處理對應事件的方法。
看起來相當神奇!當線程結束的時候,會輸出hello 3,此時的CPU占用如下
除了以上實現方式之外,還有更優雅的實現:
/* //占用0%的CPU BOOL shouldKeepRunning = YES; // global NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; // adding some input source, that is required for runLoop to runing while (shouldKeepRunning && [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]); // starting infinite loop which can be stopped by changing the shouldKeepRunning's value */ /* //占用0%的CPU @autoreleasepool { NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; [runLoop addPort:[NSMachPort port] forMode:NSRunLoopCommonModes]; [runLoop run]; } */
3、總結
iOS中的NSThread是對unix 中 pthread的一種封裝,並加入了Runloop的概念,以這種事件驅動線程的方式優化整體性能,也方便線程的調度使用。
4、源代碼
https://github.com/liqiushui/NSThreadKeepAlive.git