我正在處理使用 NSUrlConnection 發出 api 請求的遺留代碼,但信號量阻止了 NSUrlConnection 委托方法。
//1
dispatch_semaphore_t semaphore;
//2
semaphore = dispatch_semaphore_create(0);
//3
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://api2.binance.com/api/v3/ticker/24hr"]];
NSURLRequest *req = [[NSURLRequest alloc]initWithURL:url];
NSURLConnection *con = [[NSURLConnection alloc]initWithRequest:req delegate:self startImmediately:YES];
[con start];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
//4 #pragma mark - NSURLConnection 委托方法
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSLog(@"receive response");
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(@"receive data");
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(@"did fail");
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
//Getting your response string
NSLog(@"did finish loading");
dispatch_semaphore_signal(semaphore);
}
沒有信號量等待委托函式被呼叫但是當我把信號量它停止所有委托
注意:我無法將舊代碼更改為 Urlsession 或 alamofire/AfNetworking,我只能使用 NSUrlConnection
uj5u.com熱心網友回復:
NSURLConnection需要一個運行回圈來解釋為什么你既不能使用這個信號量模式(因為你會阻塞運行回圈需要的執行緒),也不能隨便將它移動到后臺執行緒(因為后臺執行緒不會有自己的運行回圈運行,因此您必須自己創建一個并在其上回圈)。
但是引入信號量是一個嚴重的錯誤。如果您背負著遺留NSURLConnection庫的負擔,并且希望向專案添加一系列順序網路請求,則應該采用異步模式,而不是在代碼庫中引入信號量。信號量是一個錯誤,因為它們會引入死鎖風險,提供非常糟糕的用戶體驗,有可能讓應用程式被看門狗行程殺死,并且對系統資源的使用效率低下。我知道信號量乍一看可能有多么吸引人(這就是為什么這么多新開發人員如此吸引它們的原因),但這幾乎總是一個錯誤。
標準答案是撰寫一個運行 的方法NSURLConnection,但如果尚不存在完成處理程式塊引數,則該方法具有完成處理程式塊引數。然后每個請求的完成處理程式塊可以發起下一個請求。還有其他更復雜的方法(例如,將其包裝在自定義異步中NSOperationQueue并將它們添加到 serial NSOperationQueue)但這些可能超出了這個問題的范圍。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/514417.html
