“This is the 16th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”
preface
Network request in most cases, we were using asynchronous way to request, so no jam interface of the main thread, but in some special cases, of multiple requests to request at the same time, the demand and the need of this a few requests to return to continue the subsequent operations, each request and are asynchronous, So how do you handle this situation?
There are many scenarios where we can make multiple requests by using the # dispatch_semaphore_t semaphore and then wait for the multiple requests to complete and receive the signal from the semaphore to perform the next step.
practice
Semaphore pass is used by both functions simultaneously
// Create a signal, value: Dispatch_semaphore_signal (<#dispatch_semaphore_t dsema) // a signal waits or waits to lower the semaphore timeout: DISPATCH_TIME_FOREVER dispatch_semaphore_wait(<#dispatch_semaphore_t dsema#>)Copy the code
Dispatch_semaphore_create uses this function to create a semaphore
The function dispatch_semaphore_signal increases the semaphore by one
The dispatch_semaphore_wait function waits for the semaphore to block the next operation and wait for the semaphore to decrease before performing the next operation
It might go something like this
- (NSDictionary *)request { __block NSDictionary *response = @{}; dispatch_semaphore_t sp = dispatch_semaphore_create(0); AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain", nil]; NSString *url = @"http://www.baidu.com"; [manager GET:url parameters:nil headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { response = responseObject; dispatch_semaphore_signal(sp); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { dispatch_semaphore_signal(sp); }]; dispatch_semaphore_wait(sp, DISPATCH_TIME_FOREVER); return response; }Copy the code
Here is a sample request example, but you will find that the main thread is stuck and cannot execute.
The reason is that when the AFN receives the returned data, it calls back to the main thread, which is now blocked and unable to perform the desired function.
How to solve this problem? It’s as simple as putting the AFN callback into a child thread
- (NSDictionary *)request { __block NSDictionary *response = @{}; dispatch_semaphore_t sp = dispatch_semaphore_create(0); AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain", nil]; Manager.com pletionQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); NSString *url = @"http://www.baidu.com"; [manager GET:url parameters:nil headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { response = responseObject; dispatch_semaphore_signal(sp); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { dispatch_semaphore_signal(sp); }]; dispatch_semaphore_wait(sp, DISPATCH_TIME_FOREVER); return response; }Copy the code
That’s the perfect solution to the problem.
conclusion
Of course, this is only one solution, there are many other solutions using queues and so on, I hope this article can help you.