[英]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.