【问题标题】:NSTimer doesn't call methodNSTimer 不调用方法
【发布时间】:2011-05-20 15:43:18
【问题描述】:

我现在真的很沮丧,用谷歌搜索了整个互联网,偶然发现了 SO,但仍然没有找到解决方案。

我正在尝试实现一个 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”由@property 定义:

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

    NSTimer *theTimer;

}

@property (nonatomic, retain) NSTimer *theTimer;

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

我做错了什么?

【问题讨论】:

  • showAlarm:(Alarm *)alarm 的方法签名应该改为showAlarm:(NSTimer *)timer。然后你会得到带有Alarm *alarm = [timer userInfo]的Alarm对象。

标签: objective-c cocoa nstimer


【解决方案1】:

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

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

改为。

【讨论】:

    【解决方案2】:

    别忘了检查是否

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

    在主线程中调用。

    【讨论】:

    • 这真的很重要!这是我的计时器没有触发的原因
    【解决方案3】:

    您已经创建了一个 NSTimer 对象,但您还没有安排它运行。 timerWithTimeInterval:target:selector:userInfo:repeats:创建一个计时器,您可以安排它稍后运行,例如,在应用程序启动时创建一个计时器,并让它在用户按下按钮时开始计数。要么打电话

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

    在 setTimerForAlarm 的末尾或替换

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

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

    创建一个计时器并立即安排它。

    【讨论】:

    • +1 表示既正确又彻底! (实际上,我必须等到午夜才能投票——我已经用完了一天的供应。)
    【解决方案4】:

    好吧,您可能希望在运行循环中实际安排您的 NSTimer :) 而不是 timerWithTimeInterval 使用 scheduledTimerWithTimeInterval

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

    【讨论】:

      【解决方案5】:

      虽然所有答案都是正确的,但还有一个更简单的解决方案,根本不涉及NSTimer。您的setTimerForAlarm: 实现可以简化为一行:

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

      【讨论】:

      • 谢谢,但此时 NSTimer 是更好的选择,因为我也想随时取消 Timer。 :-)
      • 你也可以用+[NSObject cancelPreviousPerformRequestsWithTarget:selector:object:]取消performSelector:withObject:afterDelay:
      • 感谢您的这篇文章!这可以节省大量时间,而且我的代码更紧凑。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-28
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 2013-11-28
      • 2011-04-30
      • 2012-10-24
      相关资源
      最近更新 更多