GCD:Grand Central Dispath "牛逼的中枢调度器";是纯C语言编写的,提供了很多比较强大的函数

GCD:优势

1.目前是苹果主推的线程管理方式

2.它会自动的利用更多的CPU资源(双核,四核)

3.它会自动的管理线程的生命周期(线程的创建/调度/销毁);

4.程序员只需要告诉GCD自己想要执行的哪些任务,不需要写一行线程管理的代码

#import "ViewController.h"
#define kURLString1 @"http://www.nbsheji.cn/uploadfiles/2010113143922418.jpg"
#define kURLString2 @"http://amuse.nen.com.cn/imagelist/11/21/9as70n3ir61b.jpg"

@interface ViewController ()
@property (retain, nonatomic) IBOutlet UIImageView *FirstView;//第一个图片
@property (retain, nonatomic) IBOutlet UIImageView *secondView;//第二个图片
@property(nonatomic,retain)NSMutableArray *dataSource;//存储请求下来的数据

@end

@implementation ViewController
//懒加载
- (NSMutableArray *)dataSource{
    if (_dataSource == nil) {
        self.dataSource = [NSMutableArray arrayWithCapacity:0];

    }

    return [[_dataSource retain]autorelease];
}

串行队列:(线程同步)添加到这个队列的任务一个接一个的执行(一个任务完成,才再去完成另一个任务)

- (IBAction)handleSerialQueue:(UIButton *)sender {
    //获取系统串行队列
    // (1)向系统的创建的串行队列中添加异步任务,还是在主线程中完成;
    // (2)向系统创建的串行队列中添加同步任务,会造成线程死锁,导致其他人无法执行;
    dispatch_queue_t queue1 = dispatch_get_main_queue();

    //01:队列的唯一标识,采用反域名形式
    //02:队列的属性类型,也就是标识这个队列是串行队列还是并行队列
    // (1)自己创建的串行队列中添加异步任务是在子线程中完成任务;
    // (2)自己创建的串行队列中添加同步任务是在主线程中完成任务;
    dispatch_queue_t queue2 = dispatch_queue_create("com.xcqnzf.xuchang", DISPATCH_QUEUE_SERIAL);
    /*
    //异步任务
    //第一个参数:任务添加到队列名称
    //第二个参数:block执行任务内容
    dispatch_async(queue2, ^{
        NSLog(@"任务1 %@  %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
    });

    dispatch_async(queue2, ^{
        NSLog(@"任务2 %@  %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
    });

    dispatch_async(queue2, ^{
        NSLog(@"任务3 %@  %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
    });

    //释放掉自己的创建的队列,出现create就要释放
    dispatch_release(queue2);
    */

    //同步任务
    dispatch_sync(queue2, ^{
        NSLog(@"任务1 %@  %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
    });

    dispatch_sync(queue2, ^{
        NSLog(@"任务2 %@  %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
    });

    dispatch_sync(queue2, ^{
        NSLog(@"任务3 %@  %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
    });

//    总结:同步任务:不管在哪一个队列中都是主线程中执行,但是不能将其添加到系统自带的串行队列中;
//        异步任务:在自己创建的串行队列中,在子线程中执行,如果是系统创建的队列在主线程中执行;
}

2.并行队列 (线程并发) 添加到此队列的任务同时执行  假象

- (IBAction)handleConcurrentQueue:(UIButton *)sender {
    //1.获取系统自带的并行队列
    //01.队列的优先级
    //02.预留参数  给0
    dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    //2.自己创建并行队列 (一般不自己创建并行队列,系统的并行队列已经够用了)
    dispatch_queue_t queue2 = dispatch_queue_create("com.xcqnzf.xuchang", DISPATCH_QUEUE_CONCURRENT);

    //同步任务
    dispatch_sync(queue1, ^{
        NSLog(@"同步任务%@  %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
    });

    //异步任务
    dispatch_async(queue2, ^{
        NSLog(@"任务1%@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
    });

    dispatch_async(queue2, ^{
        NSLog(@"任务2%@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
    });

    dispatch_async(queue2, ^{
        NSLog(@"任务3%@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
        //线程间的通信
        //由子线程回到主线程
        //获取系统的串行队列
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"我回到主线程了");

        });

    });

    //释放出现create就要释放
    dispatch_release(queue2);

}

3.分组队列:把多个任务添加到一个分组中执行,此时会在所有的任务完成后会自动发一个通

知,dispatch_group_notifity接收这个消息,然后在所有任务完成之后处理

- (IBAction)handleGroupQueue:(UIButton *)sender {
    //1.创建并行队列,并执行任务
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    __block typeof(self)weakSelf = self;
    //创建分组异步同步任务
    dispatch_group_t group = dispatch_group_create();
    //01.分组名
    //02.要添加的队列名
    //03.要执行的任务
    dispatch_group_async(group, queue, ^{

        NSURL *urlString = [NSURL URLWithString:kURLString1];
        NSData *data1 = [NSData dataWithContentsOfURL:urlString];
        //使用数组存放请求下来的数据
        [weakSelf.dataSource addObject:data1];

    });

dispatch_group_async(group, queue, ^{

        NSURL *url = [NSURL URLWithString:kURLString2];
        NSData *data2 = [NSData dataWithContentsOfURL:url];
    [weakSelf.dataSource addObject:data2];

    });

    //分组中的任务都完成后会自动触发下面的方法
    dispatch_group_notify(group, queue, ^{

        weakSelf.FirstView.image = [UIImage imageWithData:weakSelf.dataSource[0]];
        weakSelf.secondView.image = [UIImage imageWithData:weakSelf.dataSource[1]];

    });
    //释放分组
    dispatch_release(group);
}

4.障碍队列

- (IBAction)handleBarrierQueue:(UIButton *)sender {
    //1.使用障碍队列只能使用自己创建的并列队列,不能使用系统的并行队列
    dispatch_queue_t  queue = dispatch_queue_create("com.xcqnzf.xuchang", DISPATCH_QUEUE_CONCURRENT);
    //2.往并行队列中添加任务
    dispatch_async(queue, ^{

        NSLog(@"A写入文件");
    });

    dispatch_async(queue, ^{

        NSLog(@"B写入文件");
    });

    dispatch_async(queue, ^{

        NSLog(@"C写入文件");
    });

    //添加障碍,间隔写入和读取的任务,障碍任务之前的任务都完成了才能继续完成障碍任务后面的任务
    dispatch_barrier_async(queue, ^{
        NSLog(@"我是障碍任务,读取的任务先等会");
    });

    dispatch_async(queue, ^{

        NSLog(@"D读取文件");
    });

    dispatch_async(queue, ^{

        NSLog(@"D读取文件");

    });

    dispatch_async(queue, ^{
        NSLog(@"E读取文件");

    });
    //3.释放
    dispatch_release(queue);

}

只执行一次

- (IBAction)handleOnce:(UIButton *)sender {

       static  dispatch_once_t oneToken ;
    //
     dispatch_once(&oneToken, ^{
         NSLog(@"有能耐让我走两次");
     });

}

这里需要写一个单例

Helper.h
@interface Helper : NSObject
+ (Helper *)shareHelper;
@end

Helper.h
@implementation Helper

static  Helper *helper = nil;
+ (Helper *)shareHelper{
//VIP
static dispatch_once_t oneToken;
dispatch_once(&oneToken, ^{
    helper = [[Helper alloc]init];
});

    return helper;

}
@end

重复任务

- (IBAction)handleRepeat:(UIButton *)sender {
    //1.获取系统的并行队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //2.向队列中添加重复任务
    //01.任务重复的次数
    //02.任务添加到的队列名称
    //03.当前是第几次重复这个任务
    dispatch_apply(10, queue, ^(size_t times) {
        NSLog(@"我要吃爆米花,这是我第%ld吃",times);

    });
}

延迟任务 一个任务要执行的时候先等上一段时间再做

- (IBAction)handlePing:(UIButton *)sender {
    //创建一个延迟任务
    //01. DISPATCH_TIME_NOW 表示从当前时间开始
    //02. 表示过多少秒才去执行任务
    //03. 串行的主队列
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"延迟任务在主线程中执行");
    });
}<pre name="code" class="objc">//释放
- (void)dealloc {
    [_FirstView release];
    [_secondView release];
    self.dataSource = nil;
    [super dealloc];
}

分组队列效果:

iOS中 GCD-Grand Central Dispath 多线程 UI_21的更多相关文章

  1. iOS中你必须了解的多线程

    多线程概念详解 什么是进程? 简单的说进程就是我们电脑上运行的一个个应用程序,每一个程序就是一个进程,并且每个进程之间是独立的,每个进程运行在其专用受保护的内存空间内(window系统可以通过任务管理 ...

  2. GCD (Grand Central Dispatch) 笔记

    GCD (Grand Central Dispatch) 是Apple公司开发的一种技术,它旨在优化多核环境中的并发操作并取代传统多线程的编程模式. 在Mac OS X 10.6和IOS 4.0之后开 ...

  3. iOS开发-多线程之GCD(Grand Central Dispatch)

    Grand Central Dispatch(GCD)是一个强有力的方式取执行多线程任务,不管你在回调的时候是异步或者同步的,可以优化应用程序支持多核心处理器和其他的对称多处理系统的系统.开发使用的过 ...

  4. 在Swift中应用Grand Central Dispatch(上)转载自的goldenfiredo001的博客

    尽管Grand Central Dispatch(GCD)已经存在一段时间了,但并非每个人都知道怎么使用它.这是情有可原的,因为并发很棘手,而且GCD本身基于C的API在 Swift世界中很刺眼. 在 ...

  5. iOS中GCD的使用小结

    http://www.jianshu.com/p/ae786a4cf3b1 本篇博客共分以下几个模块来介绍GCD的相关内容: 多线程相关概念 多线程编程技术的优缺点比较? GCD中的三种队列类型 Th ...

  6. 在Swift中应用Grand Central Dispatch(下)

    在第一部分中, 你学到了并发,线程以及GCD的工作原理.通过使用dispatch_barrrier和dispatch_sync,你做到了让 PhotoManager单例在读写照片时是线程安全的.除此之 ...

  7. iOS中进程与线程(多线程、主次线程)

    一.什么是线程?什么是多线程?              线程是用来执行任务的,线程彻底执行完任务A才能去执行任务B.为了同时执行两个任务,产生了多线程. 例子: 打开一个音乐软件,用户开辟一个线程A ...

  8. Swift - 多线程实现方式(3) - Grand Central Dispatch(GCD)

    1,Swift继续使用Object-C原有的一套线程,包括三种多线程编程技术: (1)NSThread (2)Cocoa NSOperation(NSOperation和NSOperationQueu ...

  9. iOS中的几种锁的总结,三种开启多线程的方式(GCD、NSOperation、NSThread)

    学习内容 欢迎关注我的iOS学习总结--每天学一点iOS:https://github.com/practiceqian/one-day-one-iOS-summary OC中的几种锁 为什么要引入锁 ...

随机推荐

  1. Linux 基本bash命令

    1.查看文件大小.内存大小.cpu信息.硬盘空间 显示当前目录所有文件大小的命令:ls -lht 内存空间.CPU信息.硬盘空间:htop.top(htop详解参考:http://blog.csdn. ...

  2. Struts中的找不到StringUtils异常

    今天在Struts2框架下使用JSON插件时,程序保存找不到类org/apache/commons/lang/xwork/StringUtils,我纳闷了,commons-lang-2.5.jar和c ...

  3. 03_OGNL

    1.值栈: 解答Struts能够直接获取属性值: 原因:Struts并不是直接通过request隐式对象中获取,而是将整个对象封装到了ValueStack值栈中,直接匹配是否存在这个属性,找到了就取出 ...

  4. Node.js URL

    稳定性: 3 - 稳定 这个模块包含分析和解析 URL 的工具.调用 require('url') 来访问模块. 解析 URL 对象有以下内容,依赖于他们是否在 URL 字符串里存在.任何不在 URL ...

  5. Lucene总结

    数据的分类 结构化数据:有固定类型或者有固定长度的数据 例如:数据库中的数据(mysql,oracle等), 元数据(就是windows中的数据) 结构化数据搜索方法: 数据库中数据通过sql语句可以 ...

  6. 在Spring Boot框架下使用WebSocket实现消息推送

    Spring Boot的学习持续进行中.前面两篇博客我们介绍了如何使用Spring Boot容器搭建Web项目(使用Spring Boot开发Web项目)以及怎样为我们的Project添加HTTPS的 ...

  7. Apache shiro集群实现 (三)shiro身份认证(Shiro Authentication)

    Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro ...

  8. Dynamics CRM2016 Web API之通过实体的primary key查询记录

    CRM2016启用了webapi 而弃用了odata,作为码农的我们又开始学习新东西了. 下面是一段简单的查询代码,通过systemuser的primary key来查询一条记录 Web API查询方 ...

  9. 你知道如何为iOS工程改名吗?

    我们在iOS开发中,难免会遇到项目做到一半要改名字的情况.如果项目名差的太大,工程名看起来总是不舒服的,有良心的开发者可能就会想着为工程改个贴切的名字,那么你就为用到本文记录的内容. 如果我们开发的两 ...

  10. FORM开发实现动态LOV

    方法一.设置lov的记录组 IF :mat_trx.trx_action_id = 1 THEN set_lov_property('lot_number',group_name,'lot_issue ...