>

使用注意事项,NSTimer使用注意事项

- 编辑:澳门新葡亰平台游戏 -

使用注意事项,NSTimer使用注意事项

 countDownTimer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(countDown:) userInfo:nil repeats:YES]; NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop]; [currentRunLoop addTimer:countDownTimer forMode:NSRunLoopCommonModes]; 
__weak typeof weak_self = self;_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:weak_self selector:@selector(onTimeout) userInfo:nil repeats:YES];

1.

scheduled开始和非schedule的起来方法的界别。系统框架提供了三种创建NSTimer的法门,当中以scheduled初叶的方法会自动把timer插手当前run loop,到了设定的小运点就能接触钦命的艺术,而从不scheduled初始的方式则须求技术员本身手动增加到timer到多少个run loop中才会有效。run loop在运作时一般有三个mode,贰个defaultmode,一个trackingmode,平常状态下run loop使用defaultmode,scheduled生成的timer会默许增多到defaultmode中,当大家互相scrollview时,run loop切换来trackingmode运维,于是大家开掘计时器失效了。为了使停车计时器在我们滑动scrollview时也能平常运作,大家供给保障defaultmode和trackingmode里都添加了作者们转移的timer。如:

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:_timeInterval target:self selector:@selector(addone) userInfo:nil repeats:YES];
 [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];

或者:

NSTimer *timer = [NSTimer timerWithTimeInterval:_timeInterval target:self selector:@selector(addone) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

blog addr:

发觉输出的log和事先的等同,难道weak对象根本没起效果?用Instrement查看了一晃内部存款和储蓄器景况,开采真便是Timer强援用Target对象

3.

在行使repeats参数为YES的计时器时,借使在动用完定时器时后并未有调取invalidate方法,导致target和userInfo未有被保释,则可能会产生巡回引用情形,进而影响内部存款和储蓄器释放。

  • NS提姆er在UITableViewCell中使用是,须要将timer加到runLoop中。

那么创立提姆er的类格局的Target对象不是传self, 而是传 wrapper 对象。另外,wrapper对象还要把Timer的事件传递到确实的target上。

2.

选拔NSTimer时,timer会保持对target和userInfo参数的强引用。独有当调取了NSTimer的invalidate方法时,NSTimer才会释放target和userInfo。生成timer的方法中假使repeats参数为NO,则电磁照望计时器触发后会自动调取invalidate方法。假若repeats参数为YES,则必要程序猿手动调取invalidate方法技术假释timer对target和userIfo的强援用。

于是,大家援用三个装进对象,让Timer强引用那个包裹对象,包装对象弱援用Target(ViewController)ViewController ---> Timer --->Wrapper ...>ViewController 那样就能够破坏环形引用。

  • 同八个timer在重复使用在此以前必需invalidate, 不然会招致以前的timer不能停掉,四个timer同一时候存在。导致的风貌正是timer相同的时间更新三遍。

从日记上来看,dealloc方法确实未有进行,并且timer事件还向来在触发。OK,既然Timer强援用了ViewController,那把ViewController改成__weak不便是足以消除难题了?于是大家把创立提姆er的代码改成

详细的 Timer Wrapper 能够看完代码 BSTimer

谈起底实际可以用dispatch_time化解强援用难点,可是dispatch_time在行车制动器踏板功用上管理起来相比麻烦。

  1. NSTimer 是内需同盟NSRunLoop 才方可健康干活的。

    + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds invocation:(NSInvocation *)invocation repeats:repeats + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:aTarget selector:aSelector userInfo:(nullable id)userInfo repeats:yesOrNo;
    

    行使这一个类措施,会自动增添到当前的RunLoop里面。关于RunLoop的介绍英特网有成都百货上千资料,推荐看看 深远精晓RunLoop。

  2. 当RunLoop处于UITrackingRunLoopMode方式的时候(滑动UIScrollView的时候),使用

    scheduledTimerWithTimeInterval:(NSTimeInterval)seconds invocation:(NSInvocation *)invocation repeats:repeats 
    

    的类形式创立的Timer,是不会接收响应事件。只有RunLoop切换来Default形式时才足以经常响应。假使期待滑动时也得以响应Timer时间,需求把Timer加到RunLoop并点超方式为NSRunLoopCommonModes

    NSTimer *timer = [NSTimer timerWithTimeInterval:0.5 target:self selector:@selector userInfo:nil repeats:YES];[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    
  1. NSTimer 会强援引 target 对象,很轻便产生内部存款和储蓄器败露只怕别的因生命周期和预期不一至导致的标题。

    大家先看一段常见的例子代码

    @implementation TViewController{ NSTimer *_timer;}- dealloc{ NSLog(@"%s", __func__);}- viewDidLoad{ [super viewDidLoad]; _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(onTimeout) userInfo:nil repeats:YES];}- onTimeout{ NSLog(@"%s", __func__);}@end
    

    世家兴许会认为,当以此ViewController被 pop 掉后会符合规律释放,timer 也会停掉。但事实上的情形不是你想的那么。以下log是Push那些ViewController后,然后点击重回的进程。

2016-03-24 00:42:19.663 NSTimerDemo[14916:3982566] -[TViewController onTimeout]2016-03-24 00:42:20.663 NSTimerDemo[14916:3982566] -[TViewController onTimeout]2016-03-24 00:42:21.663 NSTimerDemo[14916:3982566] -[TViewController onTimeout]2016-03-24 00:42:22.663 NSTimerDemo[14916:3982566] -[TViewController onTimeout]2016-03-24 00:42:23.369 NSTimerDemo[14916:3982566] -[TViewController viewDidDisappear:]2016-03-24 00:42:23.663 NSTimerDemo[14916:3982566] -[TViewController onTimeout]2016-03-24 00:42:24.663 NSTimerDemo[14916:3982566] -[TViewController onTimeout]2016-03-24 00:42:25.663 NSTimerDemo[14916:3982566] -[TViewController onTimeout]

此时此刻重假设居于七个闭环的事态,咱们要想办法打破这种状态,况且__weak设置给Timer也不会损坏Timer强引用Target。

NSTimer是ios上相比常用的反应计时器组件,在接纳了一段时间后,开掘有一点地方是索要留心一下的。

 @Interface Wrapper @property (weak, nonatom) id target; @end

翻开了须臾间官方文书档案关于target的一些认证

图片 1Timer Retain Target

target:The object to which to send the message specified by aSelector when the timer fires. ***The timer maintains a strong reference to target *** until it (the timer) is invalidated.

本文由java编程发布,转载请注明来源:使用注意事项,NSTimer使用注意事项