[英]Objective-C: Blocking a Thread until an NSTimer has completed (iOS)
我一直在寻找并尝试为自己编程,这个问题的答案。
我的 mainView 控制器中有一个辅助线程在运行,然后运行一个倒计时到 0 的计时器。
虽然这个计时器正在运行启动计时器的辅助线程,但无论如何都应该暂停/阻塞。
当计时器达到 0 时,辅助线程应该继续。
我已经尝试过 NSCondition 和 NSConditionLock 都无济于事,所以理想情况下我喜欢用代码解决我的问题的解决方案,或者为我指出如何解决这个问题的指南。 不是简单地说明“使用 X”的那些。
- (void)bettingInit {
bettingThread = [[NSThread alloc] initWithTarget:self selector:@selector(betting) object:nil];
[bettingThread start];
}
- (void)betting {
NSLog(@"betting Started");
for (int x = 0; x < [dealerNormalise count]; x++){
NSNumber *currSeat = [dealerNormalise objectAtIndex:x];
int currSeatint = [currSeat intValue];
NSString *currPlayerAction = [self getSeatInfo:currSeatint objectName:@"PlayerAction"];
if (currPlayerAction != @"FOLD"){
if (currPlayerAction == @"NULL"){
[inactivitySeconds removeAllObjects];
NSNumber *inactivitySecondsNumber = [NSNumber numberWithInt:10];
runLoop = [NSRunLoop currentRunLoop];
betLooper = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(betLoop) userInfo:nil repeats:YES];
[runLoop addTimer:[betLooper retain] forMode:NSDefaultRunLoopMode];
[runLoop run];
// This Thread needs to pause here, and wait for some input from the other thread, then continue on through the for loop
NSLog(@"Test");
}
}
}
}
- (void)threadKiller {
[betLooper invalidate];
//The input telling the thread to continue can alternatively come from here
return;
}
- (void)betLoop {
NSLog(@"BetLoop Started");
NSNumber *currentSeconds = [inactivitySeconds objectAtIndex:0];
int currentSecondsint = [currentSeconds intValue];
int newSecondsint = currentSecondsint - 1;
NSNumber *newSeconds = [NSNumber numberWithInt:newSecondsint];
[inactivitySeconds replaceObjectAtIndex:0 withObject:newSeconds];
inacTimer.text = [NSString stringWithFormat:@"Time: %d",newSecondsint];
if (newSecondsint == 0){
[self performSelector:@selector(threadKiller) onThread:bettingThread withObject:nil waitUntilDone:NO];
// The input going to the thread to continue should ideally come from here, or within the threadKiller void above
}
}
您不能在线程上运行计时器并同时使线程休眠。 您可能需要重新考虑是否需要线程。
这里有几件事需要指出。 首先,当您安排计时器时:
betLooper = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(betLoop:)
userInfo:nil
repeats:YES];
它通过该方法添加到当前运行循环中并由其保留,因此您无需手动执行此操作。 只是[myRunLoop run]
。 您的计时器的选择器参数也无效——计时器的“目标方法” 需要如下所示:
- (void)timerFireMethod:(NSTimer *)tim;
这也意味着如果您想做的只是使其无效,则不需要保留计时器,因为您将从该方法内部获得对它的引用。
其次,不清楚“该线程需要休眠以等待输入”是什么意思。 当您安排该计时器时,将在同一线程上调用该方法 ( betLoop
)。 如果您要使线程休眠,则计时器也会停止。
您似乎对方法/线程有些困惑。 方法betting
正在您的线程上运行。 它本身不是一个线程,并且可以从betting
中调用其他方法,这些方法也将在该线程上。 如果你想让一个方法等待另一个方法完成,你只需在第一个方法中调用第二个方法:
- (void)doSomethingThenWaitForAnotherMethodBeforeDoingOtherStuff {
// Do stuff...
[self methodWhichINeedToWaitFor];
// Continue...
}
我想你只是想让betting
回归; 运行循环将保持线程运行,正如我所说,您从线程上的方法调用的其他方法也在线程上。 然后,当你完成倒计时,调用另一个方法来做任何需要完成的工作(你也可以使betLoop:
的计时器失效),并完成线程:
- (void)takeCareOfBusiness {
// Do the things you were going to do in `betting`
// Make sure the run loop stops; invalidating the timer doesn't guarantee this
CFRunLoopStop(CFRunLoopGetCurrent());
return; // Thread ends now because it's not doing anything.
}
最后,由于定时器的方法在同一个线程上,所以不需要使用performSelector:onThread:...
; 只需正常调用该方法。
您应该查看Threading Programming Guide 。
另外,不要忘记释放您创建的bettingThread
对象。
NSThread
有一个类方法+ (void)sleepForTimeInterval:(NSTimeInterval)ti
。 看看这个:)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.