使用信号量使AFNetworking异步变同步(dispatch_semaphore_t)

背景

  • 当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;
}

大功告成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值