2011-05-20 151 views
9

现在我真的很沮丧,搜索整个互联网,偶然发现,仍然没有找到解决方案。NSTimer不会调用方法

我想实现一个NSTimer,但我定义的方法没有被调用。 (秒设置正确,用断点检查它)。下面是代码:

- (void) setTimerForAlarm:(Alarm *)alarm { 
    NSTimeInterval seconds = [[alarm alarmDate] timeIntervalSinceNow]; 
    theTimer = [NSTimer timerWithTimeInterval:seconds 
          target:self 
          selector:@selector(showAlarm:) 
          userInfo:alarm repeats:NO]; 
} 

- (void) showAlarm:(Alarm *)alarm { 
    NSLog(@"Alarm: %@", [alarm alarmText]); 
} 

对象 “theTimer” 是deined与@property:

@interface FooAppDelegate : NSObject <NSApplicationDelegate, NSWindowDelegate> { 
@private 

    NSTimer *theTimer; 

} 

@property (nonatomic, retain) NSTimer *theTimer; 

- (void) setTimerForAlarm:(Alarm *)alarm; 
- (void) showAlarm:(Alarm *)alarm; 

我在做什么错?

+2

'showAlarm:(Alarm *)alarm'的方法签名应该是'showAlarm:(NSTimer *)timer'。然后,您将得到具有Alarm * alarm = [timer userInfo]'的Alarm对象。 – 0xced 2011-05-20 18:49:04

+0

谢谢,已经得到了;-) – tamasgal 2011-05-20 22:19:57

回答

27

timerWithTimeInterval只是创建一个计时器,但不会将其添加到任何运行循环中以供执行。尝试

self.theTimer = [NSTimer scheduledTimerWithTimeInterval:seconds 
         target:self 
         selector:@selector(showAlarm:) 
         userInfo:alarm repeats:NO]; 

改为。

+0

好的,那是显而易见的;-)我只是在所有的例子中忽略了它...... – tamasgal 2011-05-20 15:55:33

7

您已创建NSTimer对象,但尚未安排它运行。 timerWithTimeInterval:target:selector:userInfo:repeatats:创建一个计时器,您可以计划稍后运行该计时器,例如,在应用程序启动时创建计时器,并在用户按下按钮时开始计时。无论是拨打

[[NSRunLoop currentRunLoop] addTimer:theTimer forMode:NSDefaultRunLoopMode] 

在setTimerForAlarm年底或

theTimer = [NSTimer scheduledTimerWithTimeInterval:seconds 
          target:self 
          selector:@selector(showAlarm:) 
          userInfo:alarm repeats:NO]; 

它创建了一个计时器,并立即安排其更换

theTimer = [NSTimer timerWithTimeInterval:seconds 
          target:self 
          selector:@selector(showAlarm:) 
          userInfo:alarm repeats:NO]; 

+0

+1是正确和彻底的! (实际上,我必须等到午夜才开始投票 - 我已经使用了我的一天的提供者。) – 2011-05-20 20:25:58

2

那么你可能想要在运行循环中实际安排你的NSTimer :)而不是timerWithTimeInterval使用scheduledTimerWithTimeInterval

theTimer = [NSTimer scheduledTimerWithTimeInterval:seconds 
         target:self 
         selector:@selector(showAlarm:) 
         userInfo:alarm repeats:NO]; 
2

虽然所有的答案是正确的,还有一个更简单的解决方案,不涉及NSTimer可言。您setTimerForAlarm:实施可以减少到一个简单的一行:

[self performSelector:@selector(showAlarm:) withObject:alarm afterDelay:[[alarm alarmDate] timeIntervalSinceNow]] 
+0

谢谢,但是NSTimer在这一点上是更好的选择,因为我也想随时取消定时器。 :-) – tamasgal 2011-05-20 22:03:23

+0

你也可以用'+ [NSObject cancelPreviousPerformRequestsWithTarget:selector:object:]'取消performSelector:withObject:afterDelay:'' – 0xced 2011-05-22 14:52:59

+1

谢谢你这篇文章!这是一个巨大的节省时间,我的代码更紧凑。 – Adrian 2015-08-09 12:27:30

8

也不要忘记检查,如果

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds 
            target:(id)target 
            selector:(SEL)aSelector 
            userInfo:(id)userInfo 
            repeats:(BOOL)repeats 

被称为主线程。

+1

这真的很重要!这是我的计时器没有开火的原因 – jere 2015-10-30 16:19:11