保定盛秋网络

0316-2636468  13831639196
  • 首页
  • H5开发
  • Android开发
  • IOS开发
  • 小程序开发
  • 新闻中心
  • 案例展示
  • 联系我们
  • 在线咨询
新闻中心

行业新闻
公司新闻
最新资讯

联系方式

盛秋网络科技(保定)有限公司
地址:保定朝阳北大街电谷酒店旁电谷中央时区B座18层
电话:0316-2636468
          13831639196
网站:www.baodingappkaifa.com

当前位置:首页 > 新闻中心> IOS开发
IOS开发

iOS开发 多线程的高级应用
2018/9/5 14:13:10 点击次数 作者

在iOS开发的道路上,多线程的重要性不言而喻. 大部分我们都停留在基础的使用上面.缺乏高级应用. 缺乏提升,是因为我们面对他太少,复杂的事情重复做,复杂的事务基础化. 差距就是这样拉开了


言归正传: 今天讲讲GCD的高级应用之信号量篇


一, 信号量的本质:

信号量的本质是数据操作锁, 它本身不具有数据交换的功能,而是通过控制其他的通信资源来实现进程间通信,它本身只是一种外部资源的标识。信号量在此过程中负责数据操作的互斥、同步等功能.


二: 信号量的工作原理


由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv),他们的行为是这样的:

P(sv):如果sv的值大于零,就给它减1;如果它的值为零,就挂起该进程的执行

V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运行,如果没有进程因等待sv而挂起,就给它加1.


举个例子,就是 两个进程共享信号量sv,一旦其中一个进程执行了P(sv)操作,它将得到信号量,并可以进入临界区,使sv减1。而第二个进程将被阻止进入临界区,因为 当它试图执行P(sv)时,sv为0,它会被挂起以等待第一个进程离开临界区域并执行V(sv)释放信号量,这时第二个进程就可以恢复执行。


三: iOS中GCD的信号量函数解析:


dispatch_semaphore_t  semaphore = dispatch_semaphore_create(2);  


这行代码创建了一个信号量,同时指明了最多有2个资源可以访问该"临界区域"


dispatch_semaphore_signal(semaphore)


这行代码 提高信号量 , 信号量计数 + 1


dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);


这行代码 降低信号量 , 信号量计数 - 1


特别注意 当信号为0(零),在执行 dispatch_semaphore_wait 语句时,信号量计数小于0 ,阻塞当前线程.


四: GCD的信号量应用场景: 控制最大并发量, 控制资源的同步访问,如数据访问,网络同步加载.


例如我有这样的一段代码,假设需求是控制两个网络的执行顺序 如想让请求一完成之后,在进行网络请求二,然后在进行网络请求N (实现的方式有多种多样)在此处主要讨论GCD semaphore 信号量的使用:


首先大家看看这段代码带来的问题


-(void)testSemaphore{


    NSLog(@"current1:%@",[NSThread currentThread]);


    dispatch_semaphore_t  semaphore = dispatch_semaphore_create(0);


    [AKkaHttpTool Post:@"https://api.douban.com/v2/book/1220562" parameters:@{@"":@""} success:^(id  _Nullable responseObject) {


        dispatch_semaphore_signal(semaphore);


    } failure:^(NSError * _Nullable error, NSInteger statusCode) {

        dispatch_semaphore_signal(semaphore);

    }];


    NSLog(@"你会来这儿吗1");

    NSLog(@"current1:%@",[NSThread currentThread]);

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); //等待信号,当信号总量少于0 的时候就会一直等待 ,否则就可以正常的执行,并让信号总量-1


    NSLog(@"你会来这儿吗2");


    [AKkaHttpTool Post:@"https://api.douban.com/v2/book/1220562" parameters:@{@"":@""} success:^(id  _Nullable responseObject) {

        NSLog(@"resqueue2:");

    } failure:^(NSError * _Nullable error, NSInteger statusCode) {

    }];

}


下面我用一张截图进行说明,主要是用于说明 dispatch_semaphore_wait 会阻塞当前线程





接下来这三个网络请求使用GCD信号量实现同步,并且不阻塞主线程


- (IBAction)gcd2:(id)sender {


   dispatch_queue_t queue = dispatch_queue_create("AkSemaphore", NULL);


   dispatch_async(queue, ^{

      NSLog(@"current1:%@",[NSThread currentThread]);

      dispatch_semaphore_t  semaphore = dispatch_semaphore_create(0);


      [AKkaHttpTool Post:@"https://api.douban.com/v2/book/1220562" parameters:@{@"":@""} success:^(id  _Nullable responseObject) {


           dispatch_semaphore_signal(semaphore);

           NSLog(@"resqueue1:");

       } failure:^(NSError * _Nullable error, NSInteger statusCode) {

           dispatch_semaphore_signal(semaphore);

       }];


       NSLog(@"你会来这儿吗1");


       dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); //等待信号,当信号总量少于0 的时候就会一直等待 ,否则就可以正常的执行,并让信号总量-1


       NSLog(@"你会来这儿吗2");


       [AKkaHttpTool Post:@"https://api.douban.com/v2/book/1220562" parameters:@{@"":@""} success:^(id  _Nullable responseObject) {

           NSLog(@"resqueue2:");

           dispatch_semaphore_signal(semaphore);

       } failure:^(NSError * _Nullable error, NSInteger statusCode) {

           dispatch_semaphore_signal(semaphore);

       }];


       dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); //等待信号,当信号总量少于0 的时候就会一直等待 ,否则就可以正常的执行,并让信号总量-1


        NSLog(@"你会来这儿吗3");

       [AKkaHttpTool Post:@"https://api.douban.com/v2/book/1220562" parameters:@{@"":@""} success:^(id  _Nullable responseObject) {

           NSLog(@"resqueue3:");   

       } failure:^(NSError * _Nullable error, NSInteger statusCode) {

       }];

    });

}




接下来讲一下控制网络的并发访问 :

假如现在有一个这样的需求,需要先下载50张图片, 一般异步会开启新的线程,但过多的线程 数与项目的性能是成反比的 . 所以控制并发,提高性能则尤为重要 : 实例代码如下


- (void)testGCD3{

    dispatch_semaphore_t semaphore =  dispatch_semaphore_create(5);

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    for (int i=0;i<100 ; i++) {


        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);


        dispatch_async(queue, ^{

            NSLog(@"i = %d",i);

            //此处模拟一个 异步下载图片的操作

            sleep(2);

            dispatch_semaphore_signal(semaphore);

        });

    }

}


本文链接:http://www.baodingappkaifa.com/content/?297.html
分享到:
点击次数:  更新时间:2018/9/5 14:13:10  【打印此页】  【关闭】
上一条:iOS开发技能树之C语言-基础知识  下一条:iOS开发效率提升小技巧

相关文章

  • APP定制开发的收费标准以及四大影响因素
  • App开发之后推广方法有哪些?
  • 运动app让你爱上运动
  • 7款优秀的App安全测试工具
  • 2019年最新AppStore 中国区下载榜前十名,有你使用的那个吗?
  • 十款超实用的APP,让自己的手机变聪明
  • 手机APP,这样使用才安全
  • APP开发为什么要用第三方?
  • iOS开发效率提升小技巧
  • iOS开发 多线程的高级应用
友情链接:廊坊短视频营销 | 廊坊小程序开发| 廊坊APP开发| 廊坊抖音推广
保定APP开发,保定APP定制开发,保定APP制作,保定小程序开发,保定软件开发-盛秋网络
首页|H5开发|Android开发|IOS开发 | 网站地图 | 站点地图

版权所有 @ 盛秋网络科技(保定)有限公司 2017 冀ICP备17018066号-2   咨询电话:0316-2636468,13831639196