iPhone:NSTimer 内存泄漏的小问题

发布于 2024-10-05 14:58:49 字数 738 浏览 1 评论 0原文

假设我有一个附加了 IBAction 的按钮,按下该按钮会触发多个操作,但必须延迟一秒触发特定操作,并且仅当用户在该延迟一秒内没有再次按下该按钮时。 代码如下所示:

   @interface Image : UIView {
           NSTimer *timer;
   }
   ...other things...;
   @end

   @implementation Image
   -(IBAction)startStopTimer{
   ...do something...;
   ...do something...;

   [timer invalidate];
   timer = [[NSTimer scheduledTimerWithTimeInterval:0.7 
      target:self 
      selector:@selector(delayedAction) 
      userInfo:nil 
      repeats:NO] retain];
   }

   -(void)delayedAction{
   ...do other things...;
   }
   @end

实际上,此代码工作得非常好:仅当用户不再按下按钮并等待至少一秒钟时才会触发“delaiAvance”。

最大的问题是:每次触发计时器时,都会发生内存泄漏。

所以,问题是:我必须如何以及在哪里发布这个 NSTimer ?

(dealloc方法中的[定时器释放]不起作用。)

suppose i have a button with an IBAction attached, which triggers several actions when pressed, BUT have to trigger a particular action with a delay of one second, AND only if the user do not press the button a new time in this delay of one second.
The code looks like this :

   @interface Image : UIView {
           NSTimer *timer;
   }
   ...other things...;
   @end

   @implementation Image
   -(IBAction)startStopTimer{
   ...do something...;
   ...do something...;

   [timer invalidate];
   timer = [[NSTimer scheduledTimerWithTimeInterval:0.7 
      target:self 
      selector:@selector(delayedAction) 
      userInfo:nil 
      repeats:NO] retain];
   }

   -(void)delayedAction{
   ...do other things...;
   }
   @end

As is, this code work very fine : "delaiAvance" is triggered only if the user DO NOT press the button one more time, and wait for at least one second.

The big problem is : each time the timer is fired, a memory leak occurs.

So, the question is : how and where do i have to release this NSTimer ?

([timer release] in dealloc method doesn't work.)

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

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

发布评论

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

评论(2

眼波传意 2024-10-12 14:58:49

据我所知,您不会保留 NSTimer 对象,因为它们是由“系统”保留的。通过执行invalidate,您可以将其从系统中释放。

无论如何,您最好的选择可能是使用performSelector:withObject:afterDelay:,因为这将允许您轻松取消触发器,并且您不必创建整个对象来执行此操作...如果我正确理解你的问题。要启动计时器,您需要执行以下操作:

- (void)buttonPressed
{
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(doSomething) object:nil];
    [self performSelector:@selector(doSomething) withObject:nil afterDelay:0.7];
}

- (void)doSomething
{
     NSLog(@"Something happens now!");
}

取消的原因是,如果您在 0.7 秒内再次单击该按钮,“计时器”将被取消并创建一个新计时器。

To my knowledge, you don't retain NSTimer objects because they are retained by the 'system'. And by doing an invalidate you release it from the system.

Your best bet is probably to use performSelector:withObject:afterDelay: anyway, since this will allow you to cancel the trigger easily and you won't have to create a whole object to do it... If I understand your question correctly. To start the timer you'd do

- (void)buttonPressed
{
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(doSomething) object:nil];
    [self performSelector:@selector(doSomething) withObject:nil afterDelay:0.7];
}

- (void)doSomething
{
     NSLog(@"Something happens now!");
}

The reason for the cancel is so that if you click the button again in the 0.7 second period, the 'timer' is canceled and a new one is created.

他夏了夏天 2024-10-12 14:58:49

所以,问题是:如何以及在哪里
我必须释放这个 NSTimer?

你不知道。运行循环会为您保留计时器,并在您调用 invalidate 方法一段时间后释放它,因此您所要做的就是在调用中删除额外的 retain scheduledTimerWithTimeInterval

So, the question is: how and where do
i have to release this NSTimer?

You don’t. The run loop retains the timer for you and releases it some time after you call the invalidate method, so that all you have to do is droping the extra retain in the call to scheduledTimerWithTimeInterval.

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