使用信号量使AFNetworking异步变同步(dispatch

2021-08-18  本文已影响0人  All_Be_Alright

背景

使用信号量来实现

// 创建一个信号,value:信号量
dispatch_semaphore_create(<#long value#>)
// 使某个信号的信号量+1
dispatch_semaphore_signal(<#dispatch_semaphore_t dsema#>)
// 某个信号进行等待或等待降低信号量 timeout:等待时间,永远等待为 DISPATCH_TIME_FOREVER
dispatch_semaphore_wait(<#dispatch_semaphore_t dsema#>, <#dispatch_time_t timeout#>)
- (NSDictionary *)httpRequest {
    __block NSDictionary *response = @{};
    dispatch_semaphore_t sem = 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;
        NSLog(@"");
        dispatch_semaphore_signal(sem);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"");
        dispatch_semaphore_signal(sem);
    }];
    
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    return response;
}

但是发现不工作,表象就是线程卡住了。
后来翻看AFNetworking源码发现NSURLSessionTaskDelegate的代理方法中


NSURLSessionTaskDelegate

成功的回调是在主线程中执行的,但是此时的主线程已经被阻塞了,所以导致失败。


主线程
- (NSDictionary *)httpRequest {
    __block NSDictionary *response = @{};
    dispatch_semaphore_t sem = dispatch_semaphore_create(0);
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
    // 给manager一个自己的线程
    manager.completionQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    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;
        NSLog(@"");
        dispatch_semaphore_signal(sem);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"");
        dispatch_semaphore_signal(sem);
    }];
    
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    return response;
}

大功告成

上一篇 下一篇

猜你喜欢

热点阅读