【问题标题】:NSTimer timerWithTimeInterval: not workingNSTimer timerWithTimeInterval:不工作
【发布时间】:2012-06-18 23:45:20
【问题描述】:

在我的项目中实现它之前,我已经创建了一个带有计时器的测试应用程序。 这是我第一次使用计时器。 但问题是当我使用 [NSTimer timerWithTimeInterval: target: selector: userInfo: repeats: ]; 实现计时器时,它不起作用。 这是我的代码, 接口:

@interface uialertViewController : UIViewController
{

    NSTimer *timer;
}

-(void)displayAlert;
-(void)hideandview;
@end

实施:

@implementation uialertViewController
- (void)viewDidLoad {

    [self displayAlert];
    [super viewDidLoad];
}


-(void)displayAlert{

    timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(hideandview) userInfo:nil repeats:NO];

    alert = [[UIAlertView alloc] initWithTitle:@"testing" message:@"hi hi hi" delegate:nil cancelButtonTitle:@"continue" otherButtonTitles:nil];
    [alert show];




    [alert release];
    alert = nil;

}

-(void)hideandview{

    NSLog(@"triggered");

    [alert dismissWithClickedButtonIndex:0 animated:YES];

    [alert release];

    [self displayAlert];
}

@end

然后我改变了 [NSTimer timerWithTimeInterval: target: selector: userInfo: repeats: ]; [NSTimer scheduledTimerWithTimeInterval: target: selector:userInfo: repeats: ]; ,它正在工作timerWithTimeInterval: 有什么问题?我在第一次实施中遗漏了什么吗?提前致谢。

【问题讨论】:

  • timerWithTimeInterval 创建计时器但不启动它,而 schedule... 会。我认为这是唯一的区别
  • @rooster117: 那我需要调用定时器触发方法,对吗?
  • 是的,或者当你想启动它时只调用 scheduleTimerWithTimeInterval 。无论哪种方式
  • 用详细代码提出的写得很好的问题!

标签: ios timer nstimer


【解决方案1】:

作为之前的回答,在主线程上注明了日程安排,但不是使用断言,而是将其放在主线程上:

@objc func update() {
    ...
}

DispatchQueue.main.async {
            self.timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(self.update), userInfo: nil, repeats: true)
        }

如果不需要异步,试试这个:

let schedule = {
            self.timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(self.update), userInfo: nil, repeats: true)
        }

        if Thread.isMainThread {
            schedule()
        }
        else {
            DispatchQueue.main.sync {
                schedule()
            }
        }

【讨论】:

    【解决方案2】:

    还可能需要确保在主线程上添加计时器。

    assert(Thread.isMainThread)
    let timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(YourSelector), userInfo: nil, repeats: true)
    

    【讨论】:

      【解决方案3】:

      两者的区别在于timerWithTimeInterval方法返回一个尚未被触发的NSTimer对象。要触发计时器,您必须使用 [timer fire]; 另一方面,scheduledTimerWithTimeInterval 返回一个已触发的 NSTimer

      所以,在您的第一个实现中,您只是缺少[timer fire];

      【讨论】:

      • 查看我的帖子 - [timer fire] 不会“启动”计时器,它只是直接调用该方法。您需要将计时器添加到运行循环中才能启动。
      • 它只工作一次,但对于连续过程使用@Joseph Humfrey 代码。
      【解决方案4】:

      scheduledTimerWithTimeInterval:invocation:repeats:scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: 创建的计时器会自动添加到 NSRunLoop,这意味着您不必自己添加它们。将它们添加到 NSRunLoop 是导致它们被触发的原因。

      使用timerWithTimeInterval:invocation:repeats:timerWithTimeInterval:target:selector:userInfo:repeats:,您必须手动将计时器添加到运行循环,代码如下:

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

      此处的其他答案建议您需要自己致电fire。你不知道 - 一旦计时器进入运行循环,它就会被调用。

      【讨论】:

      • 很好的解释!谢谢!
      • 即使使用预定的方法,如果在命令行实用程序中运行,您仍然需要手动添加它来执行 mainRunLoop,至少根据我的经验,以及如下所示:run run run nsrunloop
      • scheduledTimer 与此建议完美配合,无需触发计时器。谢谢
      • 我尝试使用 scheduleTimer 方法而不触发它,但它不起作用。但我完全同意你的回答,你不必将它添加到运行循环中。感谢您澄清差异。
      猜你喜欢
      • 1970-01-01
      • 2012-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多