当我执行此代码:
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(showButtons) userInfo:nil repeats:NO];
我需要它为零或释放它,OT不管内存管理?
我使用ARC
当我执行此代码:
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(showButtons) userInfo:nil repeats:NO];
我需要它为零或释放它,OT不管内存管理?
我使用ARC
是的, NSTimer
将保持强大的参照target
,这可能会导致(特别是在重复计时器)强参考周期(也称为保持周期)。 在你的榜样,但是,计时器不重复,只有0.5被延迟,因此最坏的情况下,你将有一个很强的参考周期,将自动解决自身在0.5秒。
但一个未解决的强基准周期的一个常见的例子是将有一个UIViewController
用NSTimer
其重复特性,但由于NSTimer
具有很强的参考UIViewController
,控制器将最终被保留。
所以,如果你保持NSTimer
作为一个实例变量,那么,是的,你应该invalidate
它,解决了有力的参考周期。 如果你只是调用scheduledTimerWithTimeInterval
,但不能将其保存到一个实例变量(作为一个可能与您的例子推测),那么你很强的参考周期将在何时解决NSTimer
完成。
而且,顺便说一下,如果你正在处理重复NSTimers
,不要试图invalidate
在他们dealloc
的所有者的NSTimer
,因为dealloc
显然不会被调用,直到有力的参考周期的解决。 在的情况下UIViewController
,例如,你可能会做在viewDidDisappear
。
顺便说一句,在先进的内存管理编程指南解释了有力的参考周期是。 显然,这是在他们的描述正确使用弱引用,这是在这里不适用(因为你有过这样的事实没有控制,其中一个部分NSTimer
使用到目标的强引用),但它确实解释的概念的强参考周期很好。
如果你不想让你NSTimer
保持强引用self
,在10.12的MacOS和iOS 10或更高版本,可以使用块再现,然后使用weakSelf
模式:
typeof(self) __weak weakSelf = self;
[NSTimer scheduledTimerWithTimeInterval:0.5 repeats:false block:^(NSTimer * _Nonnull timer) {
[weakSelf showButtons];
}];
顺便说一句,我注意到你打电话showButtons
。 如果你想只显示在您的视图中的某些控件,您可以消除使用的NSTimer
干脆做这样的事情:
self.button1.alpha = 0.0;
self.button2.alpha = 0.0;
[UIView animateWithDuration:0.25
delay:0.5
options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
animations:^{
self.button1.alpha = 1.0;
self.button2.alpha = 1.0;
}
completion:nil];
这不吃亏的保留问题NSTimer
对象,并执行双方的延迟以及按钮(一个或多个)的优美表现都在一个声明。 如果你是在为你做额外的处理showButtons
方法,你可以把在completion
块。
如果您在属性保存它,那么,你就需要将其设置为nil之后它发射的选择。
这也是安全的,它保存在你的情况下得到的类释放不管出于什么原因,这样就可以[timer invalidate]
如果你需要。
是的,可以使用: myTimer=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(showButtons) userInfo:nil repeats:NO];
然后在您的viewDidDisappear [myTimer invalidate]
使用了一个封闭定时器的新方法
timer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true, block: {[weak self] (timer) in
print("Tick tock")
guard let ws = self else { return }
//some action that repeats
ws.myViewControllerMethod()
})