我可以在@selector
中使用NSTimer
发送参数吗?如果我要发布NSTimer
,请在dealloc
中执行以下步骤吗?
[timer invalidate];
[timer release];
答案 0 :(得分:15)
[timer release]
。来自Apple's documentation:
因为运行循环维护计时器,所以从内存管理的角度来看,一旦计划完毕,通常不需要保留对计时器的引用。由于在将方法指定为选择器时将计时器作为参数传递,因此可以在该方法中适当时使重复计时器无效。但是,在许多情况下,您还需要选择使计时器失效 - 甚至可能在启动之前。在这种情况下,您需要保留对计时器的引用,以便您可以在适当的时候向其发送无效消息。如果您创建一个未安排的计时器(请参阅“Unscheduled Timers”),那么您必须保持对计时器的强引用(在引用计数环境中,保留它),以便在使用它之前不会取消分配。
这是什么意思?
如果您alloc
和init
是计时器,您还必须release
,如下所示:
NSTimer * timer = [[NSTimer alloc] initWith...];
NSRunLoop * runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
[timer release];
...
...
[timer invalidate];
timer = nil;
一旦计时器被添加到运行循环中,就没有理由继续对它进行引用,因为运行循环拥有它。在这种情况下,如图所示,只要将计时器添加到运行循环中,就会release
计时器,然后在完成后只需invalidate
。最后一行(将计时器设置为nil
)是为了安全起见。对invalidate
的调用将导致计时器被释放(通过运行循环),因此保持指向它的引用是不安全的。将本地引用设置为nil
会使事情变得犹豫不决。
但是,如果您使用以下方便方法之一创建计时器:
NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval ...];
你不根本不需要致电[timer release]
!方便方法将计时器添加到运行循环,然后运行循环拥有它,因此您不需要对返回的计时器对象执行任何内存管理。当您不再想要使用它时,您只需invalidate
计时器:
[timer invalidate];
timer = nil;
或者,如果计时器未设置为重复,则您将完全不做任何操作,因为它将在第一次调用后释放。
答案 1 :(得分:8)
这两种方法做了不同的事情。如果您拥有一个计时器(您保留它,或分配它,或复制它),那么您应该释放它。如果您在运行循环上安排它,那么您必须使其无效,以便运行循环释放它。如果你做了两件事,那么你必须释放并使计时器无效(但是通常让运行循环拥有计时器就足够了。)
答案 2 :(得分:1)
总是,释放是你做的最后一件事。一旦你发布了一些内容,就无法保证取消引用该对象是安全的,这意味着它不再能安全地发送任何消息。
答案 3 :(得分:0)
这是解除分配可能仍在运行的计时器(并且您想要停止)的正确方法。