(NSTimer 释放和失效)的第一步是什么?

发布于 2024-07-27 14:57:49 字数 194 浏览 1 评论 0原文

我可以在 NSTimer 中使用 @selector 发送参数吗? 如果我想释放 NSTimer,在 dealloc 中执行以下步骤是否正确?

[timer invalidate];
[timer release];

Can I send argument with @selector in NSTimer? If I want to release NSTimer, are the following steps right in dealloc?

[timer invalidate];
[timer release];

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不美如何 2024-08-03 14:57:49

仅当您“拥有”计时器时才需要调用[timer release]。 来自 Apple 文档:

因为运行循环维护计时器,所以从内存管理的角度来看,一旦安排了计时器,通常就不需要保留对计时器的引用。 由于当您将其方法指定为选择器时,计时器会作为参数传递,因此您可以在该方法中适当的时候使重复计时器无效。 然而,在许多情况下,您还希望选择使计时器无效——甚至可能在计时器启动之前。 在这种情况下,您确实需要保留对计时器的引用,以便您可以在适当的时候向其发送无效消息。 如果您创建一个未计划的计时器(请参阅 “非计划计时器”),那么您必须维护对计时器的强引用(在引用计数环境中,您保留它),以便在使用它之前不会释放它。

这是什么意思?

如果您分配init一个计时器,您还必须释放它,如下所示:

NSTimer * timer = [[NSTimer alloc] initWith...];

NSRunLoop * runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
[timer release];

...
...

[timer invalidate];
timer = nil;

将计时器添加到运行循环后,就会有没有理由再保留对它的引用,因为运行循环拥有它。 在这种情况下,如图所示,您将在将计时器添加到运行循环后立即释放计时器,然后在完成后简单地使其无效。 最后一行(将计时器设置为nil)是为了安全起见。 对 invalidate 的调用将导致计时器被释放(通过运行循环),因此保留指向它的引用是不安全的。 将本地引用设置为 nil 可以保持干净。

但是,如果您使用如下所示的便捷方法之一创建计时器:

NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval ...];

您根本不需要调用[timer release]! 便捷方法将计时器添加到运行循环中,然后运行循环拥有它,因此您不需要对返回的计时器对象执行任何内存管理。 当您不想再使用计时器时,只需使其无效即可:

[timer invalidate];
timer = nil;

或者,如果计时器未设置为重复,则您绝对不会执行任何操作,因为它将在第一次调用后被释放。

[timer release] only needs to be called if you "own" the timer. From Apple's documentation:

Because the run loop maintains the timer, from the perspective of memory management there's typically no need to keep a reference to a timer once you’ve scheduled it. Since the timer is passed as an argument when you specify its method as a selector, you can invalidate a repeating timer when appropriate within that method. In many situations, however, you also want the option of invalidating the timer—perhaps even before it starts. In this case, you do need to keep a reference to the timer, so that you can send it an invalidate message whenever is appropriate. If you create an unscheduled timer (see “Unscheduled Timers”), then you must maintain a strong reference to the timer (in a reference-counted environment, you retain it) so that it is not deallocated before you use it.

What does this mean?

If you alloc and init a timer, you must also release it, like so:

NSTimer * timer = [[NSTimer alloc] initWith...];

NSRunLoop * runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
[timer release];

...
...

[timer invalidate];
timer = nil;

Once the timer has been added to the run loop, there is no reason to keep a reference to it anymore, since the run loops owns it. In this case, as shown, you would release the timer as soon as you add it to the run loop, and then simply invalidate it when you are finished. The final line (setting timer to nil) is for safety. The call to invalidate will result in the timer being released (by the run loop), so it is unsafe to keep a reference that points to it. Setting the local reference to nil keeps things kosher.

If, however, you create a timer using one of the convenience methods like so:

NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval ...];

You do not need to call [timer release] at all! The convenience method adds the timer to the run loop, which then owns it, so you do not need to perform any memory management on the returned timer object. You would simply invalidate the timer when you no longer want to use it:

[timer invalidate];
timer = nil;

Or, if the timer was not set to repeat, you would do absolutely nothing at all, since it would be released after its first invocation.

你丑哭了我 2024-08-03 14:57:49

这两种方法做不同的事情。 如果您拥有一个计时器(您保留了它,或分配了它,或复制了它),那么您应该释放它。 如果您将其安排在运行循环上,则必须使其无效才能让运行循环释放它。 如果您做了这两件事,那么您必须释放并使计时器无效(但是通常让运行循环拥有计时器就足够了)。

The two methods do different things. If you own a timer (you retained it, or alloced it, or copied it) then you should release it. If you scheduled it on a run loop, then you must invalidate it for the run loop to release it. If you did both things, then you must release and invalidate the timer (however usually having the run loop owning the timer is sufficient).

☆獨立☆ 2024-08-03 14:57:49

总是,释放是你做的最后一件事。 一旦释放某些内容,就无法保证取消引用该对象是安全的,这意味着向其发送任何消息都不再安全。

Always, release is the last thing you do. Once you release something there is no guarantee it is safe to dereference the object, which means it no longer safe to send it ANY message.

飘然心甜 2024-08-03 14:57:49

这是释放可能仍在运行(并且您想停止)的计时器的正确方法。

That is the correct way to deallocate a timer that might still be running (and you want to stop).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文