zoukankan      html  css  js  c++  java
  • NSTimer与NSRunLoop的关系分析

    NSTimer与NSRunLoop的关系分析

    最近关于NSTimer和NSRunLoop的关系,做了一个小试验。代码地址:https://github.com/TianLibin/timerRunLoopTest.git

    代码运行效果如下图所示:
    1550680E-C39B-4F0E-80D1-7E40A8ADA61E

    本示例演示了四个定时器的效果以及界面操作对它们的影响。
    前两个定时器,是在子线程中启动的:

    - (void)subThread1
    {
        @autoreleasepool {
            self.subThreadTimer1 = [NSTimer scheduledTimerWithTimeInterval:1.0f
                                                                    target:self
                                                                  selector:@selector(subThread1Fun:)
                                                                  userInfo:nil
                                                                   repeats:YES];
        }
    }
    
    - (void)subThread2
    {
        @autoreleasepool {
            self.subThreadTimer2 = [NSTimer scheduledTimerWithTimeInterval:1.0f
                                                                    target:self
                                                                  selector:@selector(subThread2Fun:)
                                                                  userInfo:nil                                                               repeats:YES];
            [[NSRunLoop currentRunLoop] run]; // 这行代码是两个定时器启动的不同之处
        }
    }
    

    但是从运行效果看,第一个标签数字没有变化,一直是0,明显是定时器没有执行到。
    两者的区别在于第二个多执行了一行代码:[[NSRunLoop currentRunLoop] run];
    因为NSRunLoop在主线程中是默认运行的,子线程中默认不运行。所以在第一个定时器中,虽然设置了定时器,但出了该线程方法,runLoop默认停止了,异步的方法也就执行不到了。
    第二个定时器,在线程中显示把runLoop运行起来了,它会一直运行下去,直到异步方法执行完毕。

    下面比较第三,四两个定时器的效果:

    - (void)startDefaultRunTimer
    {
        self.defaultRunTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f
                                                                target:self
                                                              selector:@selector(defaultRunFun:)
                                                              userInfo:nil
                                                               repeats:YES];
    }
    
    - (void)startCommonRunTimer
    {
        self.commonRunTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f
                                                                target:self
                                                              selector:@selector(commonRunFun:)
                                                              userInfo:nil
                                                               repeats:YES];
        // 下面一行代码是这两个定时器启动的不同之处
        [[NSRunLoop currentRunLoop] addTimer:self.commonRunTimer forMode:NSRunLoopCommonModes]; 
    }
    

    从开始运行,这两个定时器没有什么不同之处。但是当我把手指按在下面左侧的滚动条上上下拖动滚动视图时,这时为了更清楚一看到区别,手指不要离开屏幕。能看到第三个标签数字停止变化,即定时器方法暂停执行了,松开手指后,数字继续变化。
    两个定时器的区别在于这句话:[[NSRunLoop currentRunLoop] addTimer:self.commonRunTimer forMode:NSRunLoopCommonModes];
    因为runLoop默认的运行模式是:NSDefaultRunLoopMode。在iOS系统下,为了提高界面的响应速度,在用于对屏幕进行操作时,会暂停一些运算,尤其是涉及到滚动视图这种需要流畅响应的视图。
    用手拖动右侧滚动试图没有影响,因为它不会上下滚动。
    所以我们显示地把这个定时器加到NSRunLoopCommonModes运行模式下,就会忽略界面操作的影响,可以不受界面操作的干扰,正常执行异步方法了。

  • 相关阅读:
    Linux 部署 nginx
    Linux 部署vue项目(使用nginx)
    git 操作规范
    mysql grant权限分配(转)。
    前端优化,包括css,jss,img,cookie
    关于js里的那一堆事件
    个人作业——软件工程实践总结作业
    Unity3D 快捷键
    Beta冲刺第二天
    Beta冲刺第一天
  • 原文地址:https://www.cnblogs.com/yingkong1987/p/3161132.html
Copyright © 2011-2022 走看看