我的NSTimer的选择器不运行。为什么?

时间:2011-11-18 14:36:19

标签: ios nstimer

我的代码是:

-(void) timerRun{...}

-(void) createTimer
{
   NSTimer *timer;
   timer = [NSTimer timerWithTimeInterval:1.0 
                                   target:self 
                                 selector:@selector(timerRun) 
                                 userInfo:nil 
                                  repeats:YES];
}

viewDidLoad
{
   [NSThread detachNewThreadSelector:@selector(createTimmer) 
                            toTarget:self withObject:nil];
   ...

}

当我调试时,方法createTimer运行正常,但方法timerRun没有运行?

3 个答案:

答案 0 :(得分:12)

只是创建一个计时器并不会启动它。您需要创建它并安排它。

如果您希望它在后台线程上运行,那么您实际上将需要做更多的工作。 NSTimer附加到NSRunloop s,它是事件循环的Cocoa形式。每个NSThread本身都有一个运行循环,但你必须告诉它显式运行。

附带定时器的运行循环可以无限期地运行,但您可能不希望它,因为它不会为您管理自动释放池。

因此,总而言之,您可能希望(i)创建计时器; (ii)将其附加到该线程的运行循环; (iii)进入一个创建自动释放池的循环,运行一个运行循环,然后排出自动释放池。

代码可能如下所示:

// create timer
timer = [NSTimer timerWithTimeInterval:1.0 
                                target:self 
                              selector:@selector(timerRun) 
                              userInfo:nil 
                               repeats:YES];

// attach the timer to this thread's run loop
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

// pump the run loop until someone tells us to stop
while(!someQuitCondition)
{
    // create a autorelease pool
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    // allow the run loop to run for, arbitrarily, 2 seconds
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];

    // drain the pool
    [pool drain];
}

// clean up after the timer
[timer invalidate];

答案 1 :(得分:5)

您必须安排计时器才能运行。它们附加到一个运行循环,然后根据需要更新计时器。

您可以将createTimer更改为

[NSTimer scheduledTimerWithTimeInterval:1.0 
                                   target:self 
                                 selector:@selector(timerRun) 
                                 userInfo:nil 
                                  repeats:YES];

或添加

[[NSRunLoop currentRunLoop] addTimer:timer forModes:NSRunLoopCommonModes];

答案 2 :(得分:2)

您在scheduledTimerWithTimeInterval中使用的方法签名:target:selector:userInfo:repeat:必须具有NSTimer的参数,因为它将自身作为参数传递。

您应将邮件签名更改为:

(void)timerRun:(NSTimer *)timer;

你不需要对参数做任何事情,但它应该在那里。同样在createTimer中,选择器将成为@selector(timerRun :),因为它现在接受一个参数:

timer = [NSTimer timerWithTimeInterval:1.0 
                              target:self 
                            selector:@selector(timerRun:) 
                            userInfo:nil 
                             repeats:YES];