NSTimer没有触发选择器

inf*_*eqd 28 nstimer ios

在带有ARC的ios5.0中,在我的rootviewcontroller中,我调用了一个由app delegate持有的安全管理器对象中的方法.在那个方法中,我按如下方式设置定时器

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self 
                                       selector:@selector(updateModel:) userInfo:str repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 
Run Code Online (Sandbox Code Playgroud)

但是,这永远不会激发选择器即.updateModel:永远不会被调用.可能有什么不对?在没有使用NStimer的情况下,还有另一种更有效的方法吗?

tma*_*hey 118

也可能是一个线程问题:

如果

[NSThread isMainThread]
Run Code Online (Sandbox Code Playgroud)

是假的然后像这样启动计时器:

dispatch_async(dispatch_get_main_queue(), ^{
        timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(tick:) userInfo:nil repeats:YES];
    })
Run Code Online (Sandbox Code Playgroud)

  • 计时器仅在主(UI)线程中正确执行.如果您尝试在主线程之外的另一个线程中启动计时器,它将不会触发. (6认同)
  • “ scheduledTimer”方法尝试使用与当前线程关联的运行循环。主线程始终具有一个运行循环,但其他线程则没有,除非您显式创建它。在这种情况下,计时器不会安排。 (3认同)

sos*_*orn 13

你似乎与你的计时器变量有点混淆.

您初始化一个新的计时器,但实际上并没有使用它.你想使用你初始化的计时器还是你想要ApplicationDelegate.timer?

以下是两种可能的解决方案.

选项一(假设您有一个名为ApplicationDelegate的类实例,并且它具有timer属性):

ApplicationDelegate.timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(updateModel:) userInfo:str repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:ApplicationDelegate.timer forMode:NSRunLoopCommonModes];
Run Code Online (Sandbox Code Playgroud)

方案二:

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(updateModel:) userInfo:str repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
Run Code Online (Sandbox Code Playgroud)

  • 第二种方式是不正确的.它试图两次添加计时器.`scheduledTimerWithTimeInterval:...`已经添加了计时器.确保你在主线程上运行它. (22认同)

WIN*_*gey 8

我遇到了同样的问题,我在主队列中触发计时器来解决它:

[NSURLConnection sendAsynchronousRequest:request queue:_operationQueue
    completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
         [self loopUpUpdateStart];
}];

-(void)loopUpUpdateStart{
    dispatch_async(dispatch_get_main_queue(), ^{

        _loopTimerForUpRevision = 
          NSTimer scheduledTimerWithTimeInterval: kNetworkLoopIntervalUpRev
                                          target: self
                                        selector: @selector(myCoolMethod)
                                        userInfo: nil
                                         repeats: YES];
        TRACE(@"Start Up updates");
    });
}
Run Code Online (Sandbox Code Playgroud)


Rob*_*ier 7

这条线有几个问题:

[[NSRunLoop currentRunLoop] addTimer:ApplicationDelegate.timer forMode:NSRunLoopCommonModes]; 
Run Code Online (Sandbox Code Playgroud)

首先,它根本不需要.-scheduledTimerWithTimeInterval:...已经将计时器添加到runloop.您无需再次添加它.

其次,局部变量timer与属性无关ApplicationDelegate.timer(可能nil在此时).

如果你正在与应用程序代表交谈,以至于你创建了一个名为ApplicationDelegate(一个全局的宏?)的东西,你就是在谈论它太多了.应用程序委托是应用程序的委托; 它有助于应用程序启动和停止以及响应系统事件.应用程序委托不是存储全局变量的地方.在任何情况下,计时器绝对不是你从另一个对象获取的东西.