NSURLSessionDataTask wait completion failed



我在Objective-c中使用NSURLSessionDataTask传递POST消息。

传输任务是非阻塞的。我必须等待结果,所以我使用dispatch_semaphore_t等待。

不幸的是,当相应的函数被调用时,任务不起作用,为什么会这样?如下所示:

NSString *urlString = [NSString stringWithFormat:@"http://localhost/api/test"];
char json_string[20] = "reqtestmsg";
size_t jsonLength = strlen(json_string);
NSData *jsonBodyData = [NSData dataWithBytes:json_string length:jsonLength];
NSMutableURLRequest *request = [NSMutableURLRequest new];
request.HTTPMethod = @"POST";
// for alternative 1:
[request setURL:[NSURL URLWithString:urlString]];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setHTTPBody:jsonBodyData];

NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config
delegate:nil
delegateQueue:[NSOperationQueue mainQueue]];
printf ("curl semaphoren");
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
__block bool result = false;
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
completionHandler:^(NSData * _Nullable data,
NSURLResponse * _Nullable response,
NSError * _Nullable error) {

NSHTTPURLResponse *asHTTPResponse = (NSHTTPURLResponse *) response;
NSLog(@"curl The response is: %@", asHTTPResponse);

if (asHTTPResponse.statusCode == 200) {
printf ("curl status 200 okn");
result = true;
}
dispatch_semaphore_signal(semaphore);
}];
[task resume];
printf ("curl wait!!!");
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); // ==> blocked , task does not work!!!! 
printf ("curl wait!!! -1");
return result;

您已指定委托队列为主队列。但是您已经用dispatch_semaphore_wait阻塞了主线程。这是一个典型的死锁,等待代码在阻塞的队列上运行。

你可以为你的会话委托队列指定nil,这样你就不会死锁。或者使用[NSURLSession sharedSession]

我还鼓励您考虑完全消除信号量。我理解信号量的吸引力,但它几乎总是错误的解决方案。苹果移除同步网络API是有原因的。信号量技巧感觉像是一种直观的解决方法,但它效率低下,导致不合格的用户体验,甚至可能导致应用程序在某些情况下被看门狗进程终止。

最新更新