【问题标题】:How to get NSTimer to loop如何让 NSTimer 循环
【发布时间】:2011-12-24 17:35:16
【问题描述】:

我正在尝试了解 NSTimer,使用 Foundation 并打印到控制台。谁能告诉我我需要做什么才能使以下工作正常工作?它编译时没有错误,但没有激活我的startTimer 方法——没有打印。

我的目标是让一个方法调用另一个方法来运行一些语句,然后在设定的时间后停止。

#import <Foundation/Foundation.h>

@interface MyTime : NSObject {
    NSTimer *timer;
}
- (void)startTimer;
@end

@implementation MyTime

- (void)dealloc {
    [timer invalidate];
    [super dealloc];
}

- (void)startTimer {
     timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(runTimer:) userInfo:nil repeats:YES];
}

- (void)runTimer:(NSTimer *)aTimer {
    NSLog(@"timer fired");
}
@end


int main(int argc, char *argv[]) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];


    MyTime *timerTest = [[MyTime alloc] init];
    [timerTest startTimer];

    [timerTest release];

    [pool release];
    return 0;
}

【问题讨论】:

  • 请奖励过去帮助过您的人,并接受您之前问题的答案。

标签: objective-c macos nstimer foundation


【解决方案1】:

计时器永远没有机会在您的程序中触发,因为程序几乎在计时器创建后立即结束。

有一个名为Run Loop 的结构负责处理输入,包括来自计时器的输入。为每个线程创建一个运行循环,但在这种情况下不会自动启动。

您需要运行运行循环并使其继续运行,直到计时器有机会触发。幸运的是,这很容易。插入:

[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:5.0]];

在发送startTimerreleasetimerTest 之间。如果您希望计时器重复,您需要继续保持运行循环处于活动状态。

请注意,您只需要在这样的简单程序中执行此操作;当您使用 GUI 创建应用程序时,运行循环将通过 Cocoa 应用程序设置过程启动,并保持活动状态直到应用程序终止。

【讨论】:

  • 我认为说“当主函数结束时,运行循环也结束”不太准确。我的意思是,退出的程序确实会终止运行循环,但这不是这里的问题。在这个特定的示例中,甚至没有启动任何运行循环。
  • @Chuck:我刚才实际上是想弄明白这一点。我的印象是循环是由 [NS?] 线程自动启动的,但我猜它实际上是由 AppKit 完成的?
  • 每个 NSThread 都有 一个 runloop,但在被告知之前它不会运行。在普通的 Cocoa 应用程序中,主循环由NSApplicationMain() 运行。我认为这就是它在文档中说该函数“运行应用程序”时所指的内容。
  • @Chuck:感谢您的澄清!
  • @pete:很高兴它有帮助。当他们解决您的问题时,请不要忘记单击此选项并回答您的其他问题。这让其他人知道问题已解决,并奖励回答者。详情请参阅meta.stackexchange.com/q/5234,正如我上面链接的那样。
【解决方案2】:

您必须在初始化后将计时器添加到默认运行循环:

[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

把这个放到-(void)startTimer.

【讨论】:

  • 我刚刚将其复制并粘贴到 -(void)startTimer 但它仍然无法正常工作。如果放在 timer 语句之上,它不会像以前那样做任何事情。如果放在下面,我会得到一个线程!坏错误。什么建议看起来不错 - 你能再试一次吗?谢谢蒂姆。
  • 把它放在下面是放置它的正确位置。问题是,在您的程序中,您正在启动计时器,然后立即释放包含它的对象并且它仍在运行循环中,因此当它被调用时,它所操作的对象(在本例中为 testTimer)已经消失了并且这就是你得到错误的原因。
  • 只有当你不使用他正在使用的 scheduleTimer 系列类时,这才是正确的。
  • 我已按照建议将其移至下方并删除了 [timerTest release];但它仍然无法正常工作 -
  • 那么关于我如何实现上述最初目标的任何想法?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多