OC 中,经常用到计时器,但OC给出的NSTimer这个定时器制作的类在使用的时候有很多问题。
首先,在使用NSTimer的过程中,我们必须注意一个内存泄漏的问题,也就是说,做到NSTimer要及时销毁。e g.
当用以上方法创建计时器的时候,我们通常时添加一个控制器上面,这样就造成了当我们的控制器在压栈的时候,不会销毁,而会继续计时。当然我们可以用如下方法解决:
但是这需要你对每一个定时器做特定的销毁,不然就会内存泄漏。为了一劳永逸,(程序猿的”病“)这我还一个解决方案:那就是创建一个计时器不直接加在所要使用的控制器上,而是在中间加一个缓冲层,即在中间加一个类A,把定时器加在类A上,外面利用这个类创建计时器,并对这个类A进行弱运用。这样就不会出现计时器不能被释放的情况了:
其次,在使用上面的方法在遇到把定时器添加到一个scrollView上的时候,我们发现在滑动scrollView的时候,我们的定时器又不动了。这时,我还有解决方案:把它添加到次线程里面去并且把其模式设为NSRunLoopCommonModes。e g.
虽然以上的方法都能解决我们的问题,但是作为程序猿都有一颗求更完美的心;因此,我去找到了NSTimer的底层构成原理GCD:用CGD制作的计时器,我们不仅不用担心其,销毁问题,也不会有在scrollView滑动的时候出现计时器停止的问题。在利用GCD的时候,我发现一篇文章是说用到了这个方法:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{});来制作了一个计时器,并且有暂停等功能(代码见github地址:https://github.com/StrongX/XTimer)
但是,我觉得这个方法来用CGD的话,并没有挖掘出其真正的强大之处,为此我也写了一个CGD的计时器:主要原理是用了dispatch_queue_t,dispatch_source_t,dispatch_source_set_timer,dispatch_source_set_event_handler几个CGD的函数来创建和处理事件,也包含了暂停、继续、销毁和重新开始功能。(代码见github地址:https://github.com/jonkerit/HHTimer)
作为一个菜鸟,写写菜鸟代码,有不足之处望大神们不吝赐教;
参考文章: