zoukankan      html  css  js  c++  java
  • Timer与RunLoop

    今天在论坛里看见有人提出这样一个问题:界面上有个scrollView 每次滑动的时候,NSTimer就停止了,为什么?

    看了下,下面的回复不少,但我感觉都没有真正解释清其中的问题,下面我来试着写一下我个人的理解

    (我基本上都是通过下面这篇文章学习的,有兴趣更深入、详细了解runloop的同学可以看看

    点击打开链接)

    首先,一个runloop下会包含很多个model,每个model下又会包含很多的timer/source/observe,同一时刻runloop只能在一种模式下运行,处理一种模式下的状态

    所以层次关系是    runloop 包含 model 包含 timer/source/observe   

    阅读下面内容时,希望你时刻意识到这个层次关系,以及mode的间“互斥”

    来看看App启动后main runloop的状态

    [objc] view plain copy
    1. CFRunLoop {  
    2.     current mode = kCFRunLoopDefaultMode  
    3.       
    4.     common modes = {  
    5.         UITrackingRunLoopMode  
    6.         kCFRunLoopDefaultMode  
    7.     }  
    8.       
    9.     common mode items = {  
    10.         source1,  
    11.         source2,  
    12.         timer1,  
    13.         timer2,  
    14.         observer1,  
    15.         observer2  
    16.         .........  
    17.     },  
    18.       
    19.     modes = {  
    20.         CFRunLoopMode  {  
    21.             sources0 =  { /* same as 'common mode items' */ },  
    22.             sources1 =  { /* same as 'common mode items' */ },  
    23.             observers = { /* same as 'common mode items' */ },  
    24.             timers =    { /* same as 'common mode items' */ },  
    25.         },  
    26.           
    27.         CFRunLoopMode  {  
    28.             sources0 =  { /* same as 'common mode items' */ },  
    29.             sources1 =  { /* same as 'common mode items' */ },  
    30.             observers = { /* same as 'common mode items' */ },  
    31.             timers =    { /* same as 'common mode items' */ },  
    32.         },  
    33.           
    34.         CFRunLoopMode  {  
    35.             ……………..  
    36.         },  
    37.           
    38.         CFRunLoopMode  {  
    39.             ………………..  
    40.         },  
    41.           
    42.         CFRunLoopMode  {  
    43.             …………….  
    44.         }  
    45.     }  
    46.     }  


    先看modes,确实如上所述,main runloop里包含了5个mode,每个mode里有含有很多的source、observers及timers

    接着注意main loop还包含的common modes以及common mode items两个属性

    common modes里面包含了一组mode(针对的是mode层级)
    common mode items(代码被我简写了)里则包含了一些timer、observer及source(针对的是timer、observer及source层级)

    什么意思呢?

    1.mode可以将自己标记为为common,标记为common的mode,都会被添加进common modes中(针对mode层级),系统默认是将kCFRunLoopDefaultMode、UITrackingRunLoopMode都放到common modes中了

    2.凡是在common mode items中包含的timer、observer及source,它们的变化及状态,都会被同步到common modes包含的modes中,也就是说它们在多个mode模式下都可以被处理(在common modes中的mode都会处理它们)

    基于以上概念,当我们执行

    [objc] view plain copy
    1. NSTimer *timer1 = [NSTimer timerWithTimeInterval:2 repeats:YES block:^(NSTimer * _Nonnull timer) {  
    2.         NSLog(@"test");  
    3.     }];  
    4.     [[NSRunLoop currentRunLoop] addTimer:timer1 forMode:NSDefaultRunLoopMode];  

    或者

     

    [objc] view plain copy
    1. [NSTimer scheduledTimerWithTimeInterval:2 repeats:YES block:^(NSTimer * _Nonnull timer) {  
    2.         NSLog(@"test");  
    3.     }];  

    时,timer只是被加到了kCFRunLoopDefaultMode模式下,当scroll被滑动时,runloop被切换到了UITrackingRunLoopMode模式下,所以timer自然就不工作了(同一时刻runloop只能在一种模式下运行,处理一种模式下的状态)

     

    解决方法是

     

    [objc] view plain copy
    1. NSTimer *timer1 = [NSTimer timerWithTimeInterval:2 repeats:YES block:^(NSTimer * _Nonnull timer) {  
    2.         NSLog(@"test");  
    3.     }];  
    4.     [[NSRunLoop currentRunLoop] addTimer:timer1 forMode:NSRunLoopCommonModes];  

    它的作用就是将timer放到了顶层main runloop的common mode items中了,这样kCFRunLoopDefaultMode和UITrackingRunLoopMode(上文说了,它们默认就是在common modes中的)就都会对该timer进行处理了。

  • 相关阅读:
    The Future of Middleware and the BizTalk Roadmap
    FW: How to spawn a process that runs under the context of the impersonated user in Microsoft ASP.NET pages
    Strips illegal Xml characters
    luogu P2280 激光炸弹(二维前缀和)
    luogu P2704 炮兵阵地(经典状态压缩DP)
    SP1716 GSS3 Can you answer these queries III (线段树维护最大连续子段和)
    二分图判定、匹配问题
    C++语法综合 | 基于char*设计一个字符串类MyString
    luogu P1044 火车进出栈问题(Catalan数)
    C++设计模式 | 三种设计模式基础
  • 原文地址:https://www.cnblogs.com/LynnAIQ/p/6122124.html
Copyright © 2011-2022 走看看