iOS 如何保持线程一直在运转

Posted 兜兜有糖的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 

 

以上是关于iOS 如何保持线程一直在运转的主要内容,如果未能解决你的问题,请参考以下文章

iOS程序启动与运转- RunLoop个人小结

Android学习小记-----监听并保存传感器数据,让service后台运行(保持CPU运转

iOS保持线程在后台运行

iOS7 + Sprite Kit:如果我正在改变场景,如何保持一个计时器一直显示?

iOS后台保活

runloop简单介绍