我试图让NSTimer
在子线程中触发。我的代码基本上是这样的:
-(void) handleTimer:(NSTimer *)theTimer {
NSLog(@"timer fired");
}
-(void) startMyThread {
// If I put timer in here, right before I start my new thread, it fires.
// [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(handleTimer:) userInfo:nil repeats:NO];
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
}
// This method is called from inside the new thread
-(void) playNote:(Note *)theNote withTemplate:(NSString *)theTemplate X:(int)x andY:(int)y {
NSLog(@"before timer");
// The timer doesn't fire in here. (But the print statements do.)
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(handleTimer:) userInfo:nil repeats:NO];
NSLog(@"after timer");
}
我真的想(读:需要?)在子线程中触发计时器,因为它将用于阻止音符播放(并且所有音符播放都需要在子线程中发生)。
我必须错过NSTimer
在子线程中的运行方式......
过早谢谢你的帮助!
答案 0 :(得分:5)
除非在运行循环中安排计时器,否则计时器不会触发。你也想避免不假思索地开辟线索。
除非你的run
方法启动一个运行循环,否则你的计时器不会触发。
更好的解决方案,顺便说一句,可能是使用GCD的dispatch_after()
。它比线程重量轻,但它取决于你需要做什么。但是,一般而言,队列是一种向应用程序添加并发性的更有效方法。
从评论中抓取代码以获得正确的格式(良好的查找):
double delayInSeconds = .2;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
NSLog(@"dispatch popped");
});
另外一个说明;您可以考虑使用其中一个全局并发队列。当主事件循环可能阻塞时,它们不会阻塞。当然,如果您要更新UI,则无论如何都必须返回到MEL。
答案 1 :(得分:3)
您应该将NSTimer
添加到currentRunLoop
。您的playNote
方法应如下所示:
-(void) playNote:(Note *)theNote withTemplate:(NSString *)theTemplate X:(int)x andY:(int)y
{
NSLog(@"before timer");
// The timer doesn't fire in here. (But the print statements do.)
NSTimer myTimer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(handleTimer:) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
NSLog(@"after timer");
}
应该这样做:)
答案 2 :(得分:0)
将计时器添加到当前runloop
和run
。
-(void) handleTimer:(NSTimer *)theTimer {
NSLog(@"timer fired");
}
-(void) startMyThread {
// If I put timer in here, right before I start my new thread, it fires.
// [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(handleTimer:) userInfo:nil repeats:NO];
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
}
// This method is called from inside the new thread
-(void) playNote:(Note *)theNote withTemplate:(NSString *)theTemplate X:(int)x andY:(int)y {
NSLog(@"before timer");
// The timer doesn't fire in here. (But the print statements do.)
NSTimer *Timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(handleTimer:) userInfo:nil repeats:NO];
NSLog(@"after timer");
[[NSRunLoop currentRunLoop] addTimer:Timer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
}
答案 3 :(得分:0)
在addTimer:
内尝试[NSRunLoop mainRunLoop]
,而不是current
!{/ p>