【问题标题】:Invalidating a NSTimer from within its invocation method从其调用方法中使 NSTimer 无效
【发布时间】:2012-05-15 10:06:12
【问题描述】:

我已经使用 [NSTimer scheduledTimerWithTimeInterval:target:selector:userInfo:] 安排了一个计时器,并希望在它触发时使其失效。

- (id)init
{
    [NSTimer scheduledTimerWithInterval:1 target:self selector:@selector(fired:) userInfo:nil repeats:YES];
}

- (void)fired:(NSTimer *)timer
{
    if (someCondition) {
        [timer invalidate];
    }
}

这是允许的吗?文档说明

您必须从安装了计时器的线程发送此消息。如果您从另一个线程发送此消息,与计时器关联的输入源可能不会从其运行循环中删除,这可能会阻止线程正常退出。

如果这不是完成此任务的正确方法:正确的方法是什么?

【问题讨论】:

    标签: objective-c ios multithreading nstimer


    【解决方案1】:

    从 fire 方法中调用 [timer invalidate] 很好,该代码将在与您创建计时器时使用的线程相同的线程中执行。

    您引用的 Apple Doc 仅警告您,如果您创建一个单独的线程并从中使计时器无效,那么,并且只有这样,应该会出现不可预测的行为。

    例如

    // Create the background queue
    dispatch_queue_t queue = dispatch_queue_create("do not do this", NULL);
    
    // Start work in new thread
    dispatch_async(queue, ^ { 
    
             // !! do not do this  !!
             if (someCondition) {
                     [yourTimer invalidate];
             }
             // or this
             [self fire:yourTimer];
    });
    
    // won’t actually go away until queue is empty
    dispatch_release(queue);
    

    【讨论】:

    • 这是一个比接受的更好的答案。非常感谢
    【解决方案2】:

    可以从触发的方法中使其无效,因为触发的方法与计时器安排在同一线程上:

    scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:

    创建并返回一个新的 NSTimer 对象,并以默认模式在当前运行循环中调度它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-24
      • 1970-01-01
      相关资源
      最近更新 更多