我的代码是:
-(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
没有运行?
答案 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];