标签:
以前没怎么了解过这个NSTimer,其实还是有挺多坑的,今天来总结一下:
首先我们一起来看这个:
我在A -> (push) -> B控制器,然后再B控制器中开启了一个NSTimer。然后我又pop到A
pop到A的时候,定时器还在运行,并且B没有被释放(未调用dealloc)。why?
这就不得不让我联想到我上篇写到的 “常驻线程”了,莫非NSTimer也是添加到了RunLoop?
这说明本例中的NSTimer确实是跑在了NSRunLoop中。
那为什么B没有释放呢?
Timer对Target进行了强引用。timer没有被释放,那么B就不会被释放了。也就走不到Dealloc了。那么我们就得在B离开的时候,要对timer进行invalidate。
- (void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; [_timer invalidate]; }
这个时候NSTimer 销毁了。pop到A的时候,有调用B的dealloc。
================ NSTimer 与 RunLoop 的关系
1.什么是NSTimer?
A timer waits until a certain time interval has elapsed and then fires, sending a specified message to a target object.
timer是一个能从某时刻或者周期性的给target对象发送一条指定的消息。
2. NSTimer的生命周期:
You specify whether a timer is repeating or non-repeating at creation time. A non-repeating timer fires once and then invalidates itself automatically, thereby preventing the timer from firing again. By contrast, a repeating timer fires and then reschedules itself on the same run loop.
A repeating timer always schedules itself based on the scheduled firing time, as opposed to the actual firing time
NSTimer 会对外界传递的target进行retain。如果是一次性调用(repeats:NO),会在本次调用之后自身invalidate,并且NSTimer retain的那个target会做一次release。
但是,如果是多次重复调用,就需要我们自己手动进行invalidate,不然NSTimer一直存在。
3. NSTimer的Tolerance(容差)
无论是单次执行的NSTimer还是重复执行的NSTimer都不是准时的,这与当前NSTimer所处的线程有很大的关系,如果NSTimer当前所处的线程正在进行大数据处理(假设为一个大循环),NSTimer本次执行会等到这个大数据处理完毕之后才会继续执行。
这期间有可能会错过很多次NSTimer的循环周期,但是NSTimer并不会将前面错过的执行次数在后面都执行一遍,而是继续执行后面的循环,也就是在一个循环周期内只会执行一次循环。
无论循环延迟的多离谱,循环间隔都不会发生变化,在进行完大数据处理之后,有可能会立即执行一次NSTimer循环,但是后面的循环间隔始终和第一次添加循环时的间隔相同。
4.Timers work in conjunction with run loops
其实上面的例子中我们使用的是“ create the timer and schedule it on the current run loop in the default mode”。这个是在主线程中,所以Runloop是开启的,不需要我们手动打开。
标签:
原文地址:http://www.cnblogs.com/Ohero/p/4828623.html