美文网首页
使用信号量使AFNetworking异步变同步(dispatch

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

作者: All_Be_Alright | 来源:发表于2021-08-18 14:57 被阅读0次

背景

  • 当H5调用OC的时候,默认是在主线程的,如果H5调用后,需要原生返回数据,而原生获取数据又是个耗时的异步操作就会有问题,比如OC是一个网络请求,那就需要等原生请求返回后,再返给H5。
  • 当然可以在网络请求返回的时候,调用H5的一个方法,但是觉得这样的实现方式有点low,所以还是想把网络请求改成同步,这样就可以解决这个问题了。

使用信号量来实现

  • 信号量的介绍
    正常的使用顺序是先降低然后再提高,这两个函数通常成对使用。
// 创建一个信号,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

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


主线程
  • 解决办法就是给manager一个自己的线程
- (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;
}

大功告成

相关文章

网友评论

      本文标题:使用信号量使AFNetworking异步变同步(dispatch

      本文链接:https://www.haomeiwen.com/subject/yoygbltx.html