文档章节

iOS多个网络请求并发

_子墨
 _子墨
发布于 2017/05/03 19:09
字数 776
阅读 20
收藏 0
//
//  ViewController.m
//  多个网络请求并发
//
//  Created by 贾则栋 on 17/4/27.
//  Copyright © 2017年 贾则栋. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 方式一:Dispatch_semaphore
    [self semaphore];
    
    // 方式二:NSOperationQueue
//    [self operationQueue];
}

#pragma mark - semaphore

- (void)semaphore
{
    /*
     信号量是一个整型值并且具有初始计数值,信号量通常支持两个操作:通知和等待。当信号被通知的时候计数值会增加,当信号量在线程上等待的时候,必要的情况下线程会被阻塞掉,直至信号被通知时计数值大于0,然后线程会减少这个计数继续工作。
     */
    
    // 根据信号量的原理,我们便可以快速的创建一个并发控制来同步任务和有限资源访问控制。
    dispatch_group_t group = dispatch_group_create();
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
    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_group_async(group, queue, ^{
            NSLog(@"%i, %@",i, [NSThread currentThread]);
            sleep(1);
            dispatch_semaphore_signal(semaphore);
        });
    }
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    
    /*上述代码,创建了一个初使值为2的semaphore,每一次for循环都会创建一个新的线程,线程结束的时候会发送一个信号,线程创建之前会信号等待,所以当同时创建了2个线程之后,for循环就会阻塞,等待有线程结束之后会增加一个信号才继续执行,如此就形成了对并发的控制,如上就是一个并发数为2的一个线程队列。
     */
    
    
    // 实例一
    [self semaphoreOne];
    // 实例二
//    [self semaphoreTwo];
}

- (void)semaphoreOne
{
    /*当并行执行的处理更新数据时,会产生数据不一致的情况,有时应用程序还会异常结束,虽然使用Serial Dipatch queue和dispatch_barrier_async函数可避免这类问题,但有必要进行更加细腻的排他控制
     */
    
    //1.创建全局队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //2.创建dispatch_semaphore_t对象
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
    
    //3.创建保存数据的可变数组
    NSMutableArray *mArray = [NSMutableArray array];
    
    //执行10000次操作
    for (int i = 0; i < 10000; i++) {   // 若不对并发队列加以控制,异常崩溃的概率会很高
        //异步添加数据
        dispatch_async(queue, ^{
            
            //数据进入,等待处理,信号量减1
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            
            //处理数据
            [mArray addObject:[NSNumber numberWithInt:i]];
            
            //数据处理完毕,信号量加1,等待下一次处理
            dispatch_semaphore_signal(semaphore);
        });
    }
    
    NSLog(@"%@", mArray);
}

// 通讯录的获取(ABAddressBookRef iOS9中被废弃)
- (void)semaphoreTwo
{
//    //新建一个通讯录类
//    ABAddressBookRef addressBooks = nil;
//    
//    if (DeviceVersion < 6.0) {
//        addressBooks = ABAddressBookCreate();
//    } else {
//        addressBooks =  ABAddressBookCreateWithOptions(NULL, NULL);
//        //获取通讯录权限
//        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
//        ABAddressBookRequestAccessWithCompletion(addressBooks, ^(bool granted, CFErrorRef error){dispatch_semaphore_signal(sema);});
//        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
//    }
}


#pragma mark - OperationQueue

- (void)operationQueue
{
    // 创建一个队列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    
    // 设置最大线程数
    queue.maxConcurrentOperationCount = 5;
    
    // 创建一个A操作
    NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i<10; i++) {
            NSLog(@"i的值是:%d",i);
        }
    }];
    
    // 创建一个B操作
    NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{
        for (int j = 0; j<20; j++) {
            NSLog(@"j的值是:%d",j);
        }
    }];
    
    // 添加依赖 B要在A打印完在进行打印 所以是B依赖于A 那么只需要添加如下代码即可完成
    // 使任务有序进行
    [operationB addDependency:operationA];
    
    // 分别加入到队列中
    [queue addOperation:operationA];
    [queue addOperation:operationB];
}

@end

© 著作权归作者所有

共有 人打赏支持
_子墨
粉丝 47
博文 157
码字总数 141425
作品 0
深圳
iOS工程师
私信 提问
2018 iOS 面试题大全(补充完整版)

原文地址:2018 iOS 面试题大全 由于原作者并没有继续更新,这里我转过来继续更新下 这个栏目将持续更新--请iOS的小伙伴关注! 1、iOS 应用导航模式有哪些? 2、iOS 中持久化方式有哪些? 3、...

Theendisthebegi
2018/11/15
0
0
(转)直接拿来用!最火的iOS开源项目(一)

AFNetworking 在众多iOS开源项目中,AFNetworking可以称得上是最受开发者欢迎的库项目。AFNetworking是一个轻量级的iOS、Mac OS X网络通信类库,现在是GitHub上第三大Objective-C库。它建立在...

孙启超
2013/06/21
0
0
iOS基础深入补完计划--NSURLSession使用详解(附Demo)

目录 前言 API Demo 前言 本文主要是把NSURLSession以及NSURLSessionTask相关的代理方法全部整理了一下。 旨在大体了解在一个iOS网络请求中、一个任务究竟经理了什么。 而我们、又能做些什么...

kirito_song
2018/05/10
0
0
iOS源码补完计划--AFNetworking 3.1.0源码研读

参拜一下AFNetworking的源码。 第四篇源码、暂时来看也是iOS方向的最后一篇、撸完准备趁着热乎撸一撸网络协议。 目录 准备工作 功能模块 AFURLSessionManager/AFHTTPSessionManager AFNetwo...

kirito_song
2018/05/25
0
0
iOS开发者学习Flutter

Flutter for iOS 开发者 本文档适用那些希望将现有 iOS 经验应用于 Flutter 的开发者。如果你拥有 iOS 开发基础,那么你可以使用这篇文档开始学习 Flutter 的开发。 开发 Flutter 时,你的 ...

鸿鹄当高远
2018/11/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周三乱弹 —— 孤独到都和病毒发生了感情了

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @-冰冰棒- :#今日歌曲推荐# 逃跑计划《一万次悲伤 (Live)》 《一万次悲伤 (Live)》- 逃跑计划 手机党少年们想听歌,请使劲儿戳(这里) 现在...

小小编辑
27分钟前
6
2
test

//// main.c// Test//// Created by 吕颖 on 2019/1/16.// Copyright © 2019年 carmen. All rights reserved.//#include <stdio.h>#include <stdlib.h>#include <t......

carmen-ly
今天
1
0
Android webview热门组件agentweb:4.0.2无法自适应的问题

Android webview热门组件agentweb:4.0.2无法自适应的问题 //设置自适应屏幕,两者合用mAgentWeb.getAgentWebSettings().getWebSettings().setUseWideViewPort(true); //将图片调整到适合w...

Gemini-Lin
今天
5
0
如何维护一个自己的 golang doc 服务

本文内容是如何维护一个golang 在线的doc 服务。 1 什么是godoc ? godoc 是 golang 官方提供的文档生成工具, 2 为什么要有godoc ? 我们经常遇到一个问题,就是代码和文档不一致,线上代码版...

鼎铭
今天
5
0
js中的对象创建的模式以及继承模式

对象创建模式: 工厂模式 构造函数模式 原型模式 继承模式 原型式继承 寄生式继承 构造函数 原型式和构造函数的组合式(缺点:运行两次超类类函数,积累函数的属性被挂载在原型对象上和实例对...

莫西摩西
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部