在UIViewController中使NSTimer无效以避免保留周期的最佳时间 [英] Best time to invalidate NSTimer inside UIViewController to avoid retain cycle

查看:91
本文介绍了在UIViewController中使NSTimer无效以避免保留周期的最佳时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有人知道何时是停止在UIViewController内部保持引用的NSTimer的最佳时间,以避免在计时器和控制器之间保留周期?

Does any one know when is the best time to stop an NSTimer that is held reference inside of a UIViewController to avoid retain cycle between the timer and the controller?

这是更详细的问题:我在UIViewController中有一个NSTimer。

Here is the question in more details: I have an NSTimer inside of a UIViewController.

在视图控制器的ViewDidLoad期间,我启动计时器:

During ViewDidLoad of the view controller, I start the timer:

statusTimer = [NSTimer scheduledTimerWithTimeInterval: 1 target: self selector: @selector(updateStatus) userInfo: nil repeats: YES];

以上导致计时器保持对视图控制器的引用。

The above causes the timer to hold a reference to the view controller.

现在我想释放我的控制器(例如,父控制器将其释放)

Now I want to release my controller (parent controller releases it for example)

问题是:我在哪里可以将呼叫发送到[ statusTimer invalidate]强制定时器释放对控制器的引用?

the question is: where can I put the call to [statusTimer invalidate] to force the timer to release the reference to the controller?

我尝试将它放在ViewDidUnload中,但是在视图收到内存警告之前不会被触发,所以不是一个好地方。我尝试了dealloc,但只要计时器还活着(鸡和鸡蛋问题),dealloc就永远不会被调用。

I tried putting it in ViewDidUnload, but that does not get fired until the view receives a memory warning, so not a good place. I tried dealloc, but dealloc will never get called as long as the timer is alive (chicken & egg problem).

有什么好建议吗?

推荐答案


  1. 您可以避免保留周期开始,例如,将计时器瞄准 StatusUpdate 对象,该对象保留非保留对您的控制器的(弱)引用,或者使用指针控制器初始化的 StatusUpdater ,保持对它的弱引用,并为您设置计时器。

  1. You could avoid the retain cycle to begin with by, e.g., aiming the timer at a StatusUpdate object that holds a non-retained (weak) reference to your controller, or by having a StatusUpdater that is initialized with a pointer your controller, holds a weak reference to that, and sets up the timer for you.


  • 您可以让视图在 -willMoveToWindow中停止计时器: 当目标窗口为 nil 时(应该处理 -viewDidDisappear:的反例)你提供的)以及 -viewDidDisappear:。这意味着您的视图将重新回到您的控制器中;你可以通过向控制器发送 -view:willMoveToWindow:消息或通过发布通知来避免进入计时器,如果你愿意的话。

  • You could have the view stop the timer in -willMoveToWindow: when the target window is nil (which should handle the counterexample to -viewDidDisappear: that you provided) as well as in -viewDidDisappear:. This does mean your view is reaching back into your controller; you could avoid reaching in to grab the timer by just send the controller a -view:willMoveToWindow: message or by posting a notification, if you care.

据推测,你是导致视图从窗口移除的那个,所以你可以添加一行来停止计时器和驱逐视图的行。

Presumably, you're the one causing the view to be removed from the window, so you could add a line to stop the timer alongside the line that evicts the view.

您可以使用非重复计时器。一旦触发它就会失效。然后,您可以在回调中测试是否应创建新的非重复计时器,如果是,则创建它。然后,不需要的保留周期将仅保持定时器和控制器对,直到下一个起火日期。只需1秒的开火日期,您就不必担心了。

You could use a non-repeating timer. It will invalidate as soon as it fires. You can then test in the callback whether a new non-repeating timer should be created, and, if so, create it. The unwanted retain cycle will then only keep the timer and controller pair around till the next fire date. With a 1 second fire date, you wouldn't have much to worry about.

每个建议,但第一个是保留周期并在适当的时间打破它的方式。第一个建议实际上避免了保留周期。

Every suggestion but the first is a way to live with the retain cycle and break it at the appropriate time. The first suggestion actually avoids the retain cycle.

这篇关于在UIViewController中使NSTimer无效以避免保留周期的最佳时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆