[英]How to make particular part of function wait in iOS
我正在嘗試執行共享操作,在此我使用異步塊調用函數,但是在下一個if語句中,我需要獲取在塊中完成的值才能繼續。 這是我的代碼,將突出顯示更多細節。 我聽說過NSLock並嘗試使用它,但是它沒有用,可能是我在做鎖操作,我對鎖不太熟悉。
-(void) shareOperation
{
__block NSString *resultText;
BOOL continueSharing;
NSLock *conditionLock=[[NSLock alloc] init];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
[conditionLock lock];
[self performSomeAsynchronousOperation completionBlock:^(NSError *tError, bool status)
{
dispatch_async(dispatch_get_main_queue(),
^{
if (status)
{
resultText = @"Operation completed. Would you like to continue?";
}
else
{
resultText = @" Operation failed. Would you still like to continue?";
}
UIAlertView *result = [UIAlertView alertViewWithTitle:nil message:resultText cancelButtonTitle:@"Cancel" otherButtonTitles:[NSArray arrayWithObjects:@"OK",nil] onDismiss:^(int buttonIndex)
{
NSLog(@"selected button index: %d",buttonIndex);
if (buttonIndex == 0)
{
continueSharing=YES;
[conditionLock unlock];
NSLog(@"We are continuing sharing :)");
}
}onCancel:^{
continueSharing=NO;
[conditionLock unlock];
NSLog(@"cancelled");
}]; [result show];
});
}];
});
}
//should continue only after earlier if block finishes, ie after getting the continueSharing value
if (continueSharing)
{
[self performSomeAnotherAsynchronousOperation];
}
}
您可以使用信號量(其設計目的是使一個線程可以等待來自另一個線程的信號,而無需使用鎖(僅用於確保不同時訪問某些共享資源),而無需使用鎖)。
因此,您應該創建一個信號燈:
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
警報視圖完成塊將發出該信號燈信號:
dispatch_semaphore_signal(semaphore);
以及您要等待該信號的位置(在performSomeAnotherAsynchronousOperation
之前):
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
我對您的代碼進行了一些調整,但最值得注意的是,通過確保在后台隊列中完成dispatch_semaphore_wait
來對其進行更改,以使其不會阻塞主隊列(您永遠不想這樣做)。 還要注意, dispatch_semaphore_signal
不在if
語句內。 結果是:
- (void)shareOperation
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
__block BOOL continueSharing = NO;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[self performSomeAsynchronousOperationWithCompletionBlock:^(NSError *tError, bool status){
dispatch_async(dispatch_get_main_queue(),^{
NSString *resultText;
if (status)
resultText = @"Operation completed. Would you like to continue?";
else
resultText = @"Operation failed. Would you still like to continue?";
UIAlertView *alertView = [UIAlertView alertViewWithTitle:nil message:resultText cancelButtonTitle:@"Cancel" otherButtonTitles:@[@"OK"] onDismiss:^(int buttonIndex) {
NSLog(@"selected button index: %d",buttonIndex);
if (buttonIndex == 0) {
continueSharing = YES;
NSLog(@"We are continuing sharing :)");
}
dispatch_semaphore_signal(semaphore);
} onCancel:^{
dispatch_semaphore_signal(semaphore);
NSLog(@"cancelled");
}];
[alertView show];
});
}];
// should continue only after earlier if block finishes, ie after getting the continueSharing value
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
if (continueSharing)
[self performSomeAnotherAsynchronousOperation];
});
}
更好的是,您不應使用諸如信號燈之類的任何阻止機制(一定不在主隊列中),而應該讓警報視圖的完成塊直接由進程本身直接啟動下一步。 我了解您說這在您的方案中不切實際,但通常是處理這些方案的正確方法。
您可以使用延遲塊
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC);
dispatch_after(delayTime, dispatch_get_main_queue(), ^(void){
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.