Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c NSTimer的内存管理--是否需要将其分配给变量?_Objective C_Cocoa_Memory Leaks_Nstimer_Foundation - Fatal编程技术网

Objective c NSTimer的内存管理--是否需要将其分配给变量?

Objective c NSTimer的内存管理--是否需要将其分配给变量?,objective-c,cocoa,memory-leaks,nstimer,foundation,Objective C,Cocoa,Memory Leaks,Nstimer,Foundation,每当我想做计时器时,我只做: [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(someMethod) userInfo:nil repe

每当我想做计时器时,我只做:

[NSTimer scheduledTimerWithTimeInterval:5.0 
                                 target:self 
                               selector:@selector(someMethod) 
                               userInfo:nil 
                                repeats:NO];
而不是

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0 
                                                  target:self 
                                                selector:@selector(someMethod) 
                                                userInfo:nil 
                                                 repeats:NO];

第一个是内存泄漏吗?正确的使用方法是什么?

这两个代码片段都没有内存问题;您只需选择与计时器交互的需求

当您计划一个计时器时,运行循环将保留它,当它触发时,将传递对计时器的引用,并使用其选择器(例如,
(void)doTimerThing:(NSTimer*)tim
1),因此您不必严格地将其放入变量中并自己保留它。苹果在《定时器编程主题》中对此进行了非常清楚的解释


但是,如果您可能希望在计时器激发之前(或在重复计时器激发之间)使其无效,则确实需要对其进行引用。在这种情况下,最好在其上调用
retain
scheduledTimerWithTimeInterval:target:…
方法返回一个您不拥有的对象,您不应该假设您不拥有的对象的内存状态(包括它们是否在自动释放池中,或者运行循环将使计时器保持多长时间)。如果您需要计时器(或任何对象)停留,您应该通过调用
retain
来声明其所有权



1请注意,计时器的方法应始终正确;代码段中的选择器看起来像是针对一个不支持的方法。计时器似乎是这样工作的,但您的操作与文档中的界面相反

两个代码段中都没有内存问题;您只需选择与计时器交互的需求

当您计划一个计时器时,运行循环将保留它,当它触发时,将传递对计时器的引用,并使用其选择器(例如,
(void)doTimerThing:(NSTimer*)tim
1),因此您不必严格地将其放入变量中并自己保留它。苹果在《定时器编程主题》中对此进行了非常清楚的解释


但是,如果您可能希望在计时器激发之前(或在重复计时器激发之间)使其无效,则确实需要对其进行引用。在这种情况下,最好在其上调用
retain
scheduledTimerWithTimeInterval:target:…
方法返回一个您不拥有的对象,您不应该假设您不拥有的对象的内存状态(包括它们是否在自动释放池中,或者运行循环将使计时器保持多长时间)。如果您需要计时器(或任何对象)停留,您应该通过调用
retain
来声明其所有权



1请注意,计时器的方法应始终正确;代码段中的选择器看起来像是针对一个不支持的方法。计时器似乎是这样工作的,但您的操作与文档中的界面相反

无论哪种方式,都没有内存泄漏。第二种解决方案只是将结果影响到一个变量,而第一种解决方案不存储结果,但效果是相同的


正如命名约定所建议的那样,给定该方法的名称
scheduledTimerWithTimeInterval:…
,您知道它将返回一个自动释放的对象(或者更准确地说,它将返回一个您不是所有者的对象,并且您不必自己发送释放)

如果不需要,您不必保留对已创建的
NSTimer
的引用:计时器将被安排在运行循环上(这就是运行循环,它将保留它直到使用为止,并在使用完成后释放,因此您不必麻烦),因此它将自行运行


但是如果不将返回的
NSTimer
存储在变量中,如在第二个代码中,则无法取消计时器。特别是,如果您设置了一个重复计时器,则需要将其存储在一个变量中,以便以后可以访问它,尤其是要向其发送一条
invalidate
消息,以便将其取消。

无论采用哪种方式,都不会出现内存泄漏。第二种解决方案只是将结果影响到一个变量,而第一种解决方案不存储结果,但效果是相同的


正如命名约定所建议的那样,给定该方法的名称
scheduledTimerWithTimeInterval:…
,您知道它将返回一个自动释放的对象(或者更准确地说,它将返回一个您不是所有者的对象,并且您不必自己发送释放)

如果不需要,您不必保留对已创建的
NSTimer
的引用:计时器将被安排在运行循环上(这就是运行循环,它将保留它直到使用为止,并在使用完成后释放,因此您不必麻烦),因此它将自行运行


但是如果不将返回的
NSTimer
存储在变量中,如在第二个代码中,则无法取消计时器。特别是,如果您设置了一个重复计时器,则需要将其存储在一个变量中,以便以后可以访问它,尤其是向其发送一条
invalidate
消息,以便将其取消。

除了前面的答案之外,如果您不需要重复计时器,则可以使用

[self performSelector:@selector(someMethod) withObject:nil afterDelay:5.0];

不要手动创建计时器。

除了前面的答案,如果不需要重复计时器,可以使用

[self performSelector:@selector(someMethod) withObject:nil afterDelay:5.0];

而不是手动创建计时器。

scheduledTimerWithTimeInterval:
不返回自动释放的对象;它返回一个不属于调用方的对象。是的,当然,但是如果你阅读了我的编辑,我解释了(以及在其他评论中)我真正的意思,并给出了关于我意思的所有精确性(如果你仔细阅读,我甚至在编辑之前就已经解释过运行循环会保留计时器)一个obj