iOS 如何保持線程一直在運轉


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 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM