有那么一个场景如下

+PayWithBlock:(NSString*(^)(NSString *message)) block;

如果 block 返回是同步的那是没有问题的,但是如果block 内容需要网络请求后才能得到,那如何处理,如下

Client {

    //开始调用

    [Pay PayWithBlock:NSString *(^)( NSString *message) {
//异步网络请求数据 return @"test";
}];
}

如果不做任何处理是无法得到网络请求的数据结果的, 因此我们在这里需要使用信号量来处理,思路如下:

 // 设置一个异步线程组
// 设置一个网络请求
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.github.com"]];
// 创建一个信号量为0的信号(红灯)
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"第一步操作");
// 使信号的信号量+1,这里的信号量本来为0,+1信号量为1(绿灯)
dispatch_semaphore_signal(sema);
}];
[task resume];
// 以下还要进行一些其他的耗时操作
NSLog(@"耗时操作继续进行");
// 开启信号等待,设置等待时间为永久,直到信号的信号量大于等于1(绿灯)
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
NSLog(@"dispatch_semaphore_wait_end");

整合一起代码如下:

Client {

    //开始调用

    [Pay PayWithBlock:NSString *(^)( NSString *message) {         // 设置一个网络请求     __block  NSString *result = nil;
         NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.github.com"]];
// 创建一个信号量为0的信号(红灯)
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"第一步操作");
// 使信号的信号量+1,这里的信号量本来为0,+1信号量为1(绿灯) result = @"我是网络请求数据";
dispatch_semaphore_signal(sema);
}];
[task resume];
// 以下还要进行一些其他的耗时操作
NSLog(@"耗时操作继续进行");
// 开启信号等待,设置等待时间为永久,直到信号的信号量大于等于1(绿灯)
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
NSLog(@"dispatch_semaphore_wait_end");
     return resutl; }];}

方案二 、使用dispatch_group_enter(group),dispatch_group_leave(group) 待续

iOS 信号量解决-网络异步请求的数据同步返回问题的更多相关文章

  1. 网络邂逅&网络异步请求

    什么是卡,网络慢,且你只能等着它加载完不能做别的事 这里便引申出网络异步请求的概念 #import "ViewController.h" @interface ViewContro ...

  2. android 网络异步加载数据进度条

    ProgressDialog progressDialog = null; public static final int MESSAGETYPE = 0; private void execute( ...

  3. ajax异步请求获取数据,实现滚动数字的效果。

    BackgroundPositionAnimate.js下载 需要导入的js: <script type="text/javascript" src="js/jqu ...

  4. 16 react 发送异步请求获取数据 和 使用Redux-thunk中间件进行 ajax 请求发送

    1.发送异步请求获取数据 1.引入 axios ( 使用 yarn add axios 进行安装 ) import axios from 'axios'; 2. 模拟 在元素完成挂载后加载数据 并初始 ...

  5. javascript 异步请求封装成同步请求

    此方法是异步请求封装成同步请求,加上token验证,环境试用微信小程序,可以修改文件中的ajax,进行封装自己的,比如用axios等 成功码采用标准的 200 到 300 和304 ,需要可以自行修改 ...

  6. 【读书笔记】iOS网络-异步请求与运行循环

    异步请求需要运行循环.当数据传递到服务器或是被客户端接收时,运行循环用于实现事件与委托对象之间的通信.异步请求在发出时,会在当前线程的运行循环上操作,这个实现细节是很重要的,因为在GCD块中或者是通过 ...

  7. IOS 网络浅析 (二 网络异步请求)

    学习网络,无论是C/S还是B/S首要的当然是向服务器发送请求,并得到响应,么有请求没有响应,那就不叫做网络了. 这边文章向大家介绍境界一下网路异步请求. *大家不要觉得我写的知识点太零散,我只是想给大 ...

  8. 解决ajax异步请求数据后swiper不能循环轮播(loop失效)问题、滑动后不能轮播的问题。

    问题描述: 1.我使用axios异步请求后台的图片进行渲染后不能实现循环轮播,也就是loop失效,但是静态写死的情况下不会出现这种问题. 2. 分析: swiper的机制是:初始化的时候将swiper ...

  9. uni-app如何解决在for循环里调用异步请求获取数据顺序混乱问题?

    总结/朱季谦 先前有一次做uni-app的js接口对接时,遇到过这样的情况,在for循环里,调用一个异步请求时,返回来的值顺序是乱的,因此,在以下的代码里,push到数组里的值,每次的顺序可能都是不一 ...

随机推荐

  1. 解决httpclient因为保持永久长连接造成连接吊死的问题

    httpclient使用了连接池,如果没有设置keep-alive策略,PoolingHttpClientConnectionManager会默认使用永久连接. 最近在调用京东api时,发现一个请求开 ...

  2. angularJS基础入门

    所用到工具:<script src="//cdn.bootcss.com/angular.js/1.5.8/angular.min.js"></script> ...

  3. PHP XML Parser 函数

    PHP XML Parser 简介 XML 函数允许您解析 XML 文档,但无法对其进行验证. XML 是一种用于标准结构化文档交换的数据格式.您可以在我们的 XML 教程 中找到更多有关 XML 的 ...

  4. 微信小程序UI------实现携程首页顶部的界面(弹性布局)

    今天写了一个携程界面的UI,利用H5的弹性盒子来实现,学过H5弹性盒子的,来看是比较方便的,因为CSS代码都差不多. 可以看看这篇博客 快速使用CSS 弹性盒子 效果图如下: 主要是携程首页的四个模块 ...

  5. CentOS开端口问题

    关闭SELINUX ##查看SELINUX状态 /usr/sbin/sestatus -v getenforce #修改config配置文件,重启后即可 vi /etc/selinux/config ...

  6. 三十 Python分布式爬虫打造搜索引擎Scrapy精讲—将selenium操作谷歌浏览器集成到scrapy中

    1.爬虫文件 dispatcher.connect()信号分发器,第一个参数信号触发函数,第二个参数是触发信号,signals.spider_closed是爬虫结束信号 # -*- coding: u ...

  7. label技巧

    问题描述: 一般都用label的for属性指定label的点击范围: <label for="male"><input type="radio" ...

  8. django中如何将多个app归到一个目录下。

    1.当startapps 生成多个app后,为了便于管理,可新建一个apps目录,把应用全部剪切进apps. 如果是在pycharm中,会提示是否自动更新路径,这里要全部选择取消. QQ群交流:697 ...

  9. 利用有道翻译Api实现英文翻译功能

    有道翻译提供了翻译和查词的数据接口.通过数据接口,您可以获得一段文本的翻译结果或者查词结果.       通过调用有道翻译API数据接口,您可以在您的网站或应用中更灵活地定制翻译和查词功能. 第一步: ...

  10. 第9课:备份mysql数据库、重写父类、unittest框架、多线程

    1. 写代码备份mysql数据库: 1)Linux下,备份mysql数据库,在shell下执行命令:mysqldump -uroot -p123456 -A >db_bak.sql即可 impo ...