的NSTimer内存管理(NSTimer memory management)

2019-07-04 01:58发布

当我执行此代码:

[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(showButtons) userInfo:nil repeats:NO];

我需要它为零或释放它,OT不管内存管理?

我使用ARC

Answer 1:

是的, NSTimer将保持强大的参照target ,这可能会导致(特别是在重复计时器)强参考周期(也称为保持周期)。 在你的榜样,但是,计时器不重复,只有0.5被延迟,因此最坏的情况下,你将有一个很强的参考周期,将自动解决自身在0.5秒。

但一个未解决的强基准周期的一个常见的例子是将有一个UIViewControllerNSTimer其重复特性,但由于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块。



Answer 2:

如果您在属性保存它,那么,你就需要将其设置为nil之后它发射的选择。

这也是安全的,它保存在你的情况下得到的类释放不管出于什么原因,这样就可以[timer invalidate]如果你需要。



Answer 3:

是的,可以使用: myTimer=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(showButtons) userInfo:nil repeats:NO]; 然后在您的viewDidDisappear [myTimer invalidate]



Answer 4:

使用了一个封闭定时器的新方法

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()
})


文章来源: NSTimer memory management