【问题标题】:Stop an NSRunLoop from a timer从计时器停止 NSRunLoop
【发布时间】:2011-07-08 06:19:31
【问题描述】:

我制作了一个带有计时器的 RunLoop,它可以更新显示倒计时的标签。一旦倒计时达到零,我需要 RunLoop 停止,对于计时器正常结束的情况,我可以使用 runUntilDate,日期为当前日期 + 倒计时时间。问题是当用户在完成之前取消按钮的倒计时。我不知道如何告诉 RunLoop 停止取消按钮操作。这是 RunLoop 的代码:

    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
                            [self methodSignatureForSelector:@selector(updateCountdownLabel:)]];
[invocation setTarget:self];
[invocation setSelector:@selector(updateCountdownLabel:)];
[[NSRunLoop mainRunLoop] addTimer:[NSTimer timerWithTimeInterval:1 invocation:invocation repeats:YES] forMode:NSRunLoopCommonModes];

该方法只是告诉标签在每个循环中减少 1。

我可以告诉取消按钮将标签更改为零,并让运行循环选择器检查值是否为零,但运行循环自己的选择器可以告诉它停止吗?

cancelPerformSelector:target:argument:

cancelPerformSelectorsWithTarget:

这些是我找到的最接近的,但它们似乎无法从 RunLoops 自己的选择器内部工作,或者至少我没有以任何方式尝试过它们。

基本上我需要让按钮告诉 RunLoop 停止,或者以某种方式从它自己的选择器中停止 RunLoop。

谢谢。

【问题讨论】:

  • 选择器只是方法的名称。我已经更正了您在我的编辑中对这个词的用法。

标签: cocoa timer nstimer nsrunloop runloop


【解决方案1】:

你还没有创建一个运行循环,你已经安排了一个计时器在主运行循环上开始。

您应该做的是将您创建的NSTimer 对象存储为实例变量,然后再在运行循环上调度计时器。

在您的updateCountdownLabel: 方法中,一旦满足您的结束条件,只需在您的计时器实例上调用-invalidate。这将从运行循环中删除计时器,并且由于您从未保留它,它将被释放。

我已经更新了使用基于选择器的 NSTimer 而不是基于 NSInvocation 的方法。这意味着回调方法签名按照您的预期定义。它还避免了将 NSTimer 对象存储在 ivar 中的需要:

- (void)startCountDown
{

    NSTimer* timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(updateCountdownLabel:) userInfo:nil repeats:YES]
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}


- (void)updateCountdownLabel:(NSTImer*)timer
{
    if(thingsAreAllDone)
    {
        [timer invalidate];
    }
}

【讨论】:

  • 这似乎不起作用,您使用“(id)anArg”的地方,真正应该去那里?我总是把计时器。在这种情况下,我有“- (void) updateCountdownLabel:(NSTimer *) timer”,之前从未尝试过放置任何不同的东西,但是当我按照我提到的那样做时,每当我使用 timer 变量时,我都会收到“本地声明”的警告计时器隐藏实例变量”。对于 if 语句,我只是检查标签是否小于或等于零。此代码不会引发错误,但不会阻止标签倒计时到负数。有什么想法吗?
  • 我已经更新了代码以使用基于选择器的NSTimer,它应该会给你想要的结果。
  • 发现问题。我只需要一个变量来将标签上的数字保存为 int,然后在 if 中使用 THAT。谢谢!
  • 这仅在它第一次触发“updateCountdownLabel”并且您立即在计时器上调用 invalidate 时才有效。如果它多次触发“updateCountdownLabel”并且决定使计时器无效,那么它不会从 NSRunLoop 中删除,或者 NSRunLoop 在幕后有另一个输入源。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-09
  • 1970-01-01
  • 1970-01-01
  • 2014-04-16
  • 1970-01-01
  • 2014-09-05
相关资源
最近更新 更多