GCD的相关函数使用

GCD

是iOS多线程实现方案之一,非常常用

英文翻译过来就是伟大的中枢调度器,也有人戏称为是牛逼的中枢调度器

是苹果公司为多核的并行运算提出的解决方案

1.一次性函数

dispatch_once

顾名思义是只执行一次的函数,注意是整个程序中只执行一次(单例模式常用到)

- (void)once {

    //一次性函数,只执行函数
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //里面默认线程安全的
        NSLog(@"------run");
    });
}

2.栅栏函数

dispatch_barrier_async

作用就是控制多线程的执行顺序

- (void)barrier {
    dispatch_queue_t queue = dispatch_queue_create("123", DISPATCH_QUEUE_CONCURRENT);

    dispatch_async(queue, ^{
        NSLog(@"_______1--------%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"_______2--------%@",[NSThread currentThread]);
    });

    //像栅栏一样,让上面的先执行完,再执行下面的
    dispatch_barrier_async(queue, ^{
        NSLog(@"----barrier-----%@",[NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"_______3--------%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"_______4--------%@",[NSThread currentThread]);
    });

}

3.快速迭代函数

dispatch_apply

作用就是开启多个线程同时完成某一件事,例如同时下载多张图片

//一般的做法
- (void)cutFromFileTo {
    //一般在子线程中做
    //创建并行队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        //起始路径
        NSString *from = @"/Users/DDZ/Desktop/From";
        //目标路径
        NSString *to = @"/Users/DDZ/Desktop/To";

        NSFileManager *mgr = [NSFileManager defaultManager];
        //获取起始路径中所有文件路径
        NSArray *subpaths = [mgr subpathsAtPath:from];

        for (int i = 0; i < subpaths.count; i++) {

            //将路径字符串进行拼接
            NSString *fromFullPath = [NSString stringWithFormat:@"%@/%@",from,subpaths[i]];
            NSString *toFullPath = [NSString stringWithFormat:@"%@/%@",to,subpaths[i]];

            [mgr moveItemAtPath:fromFullPath toPath:toFullPath error:nil];

        }
        NSLog(@"剪切成功");

    });
}

//使用快速迭代进行剪切
- (void)cutFileApply {
    //起始路径
    NSString *from = @"/Users/DDZ/Desktop/From";
    //目标路径
    NSString *to = @"/Users/DDZ/Desktop/To";

    NSFileManager *mgr = [NSFileManager defaultManager];
    //获取起始路径中所有文件路径
    NSArray *subpaths = [mgr subpathsAtPath:from];

    dispatch_apply(subpaths.count, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t index) {

        NSString *subpath = subpaths[index];
        //将路径字符串进行拼接
        NSString *fromFullPath = [NSString stringWithFormat:@"%@/%@",from,subpath];
        NSString *toFullPath = [NSString stringWithFormat:@"%@/%@",to,subpath];

        //剪切
        [mgr moveItemAtPath:fromFullPath toPath:toFullPath error:nil];

    });

}

一般的方法只能一张图片剪切完之后,再进行下一张得剪切

而使用快速迭代则可以同时进行剪切。

4.队列组

dispatch_group_async

与栅栏函数有相同的目的,为了控制多线程的执行顺序

例如下载两张图片之后,再将这两者合并成新的图片并显示。

必须得先下完之后才能合并吧!(顺序问题,多线程是不可控的)

//队列组
- (void)group {

    //创建组
    dispatch_group_t group = dispatch_group_create();

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    //1.下载图片1
    dispatch_group_async(group, queue, ^{

        //实现下载
        NSURL *url = [NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/6c224f4a20a446230761b9b79c22720e0df3d7bf.jpg"];
        NSData *data = [NSData dataWithContentsOfURL:url];
        //生成图片
        self.img1 = [UIImage imageWithData:data];

    });

    //2.下载图片2
    dispatch_group_async(group, queue, ^{

        //实现下载
        NSURL *url = [NSURL URLWithString:@"http://h.hiphotos.baidu.com/image/pic/item/b812c8fcc3cec3fd5b9db074d488d43f8794270b.jpg"];
        NSData *data = [NSData dataWithContentsOfURL:url];
        self.img2 = [UIImage imageWithData:data];

    });

    //3.将图片1,图片2合成一张新的图片
    dispatch_group_notify(group, queue, ^{
        //开启新的图形上下文
        UIGraphicsBeginImageContext(CGSizeMake(200, 200));

        //绘制图片
        [self.img1 drawInRect:CGRectMake(0, 0, 100, 200)];

        [self.img2 drawInRect:CGRectMake(100, 0, 100, 200)];

        //取得上下文中的图片
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

        //结束上下文
        UIGraphicsEndImageContext();

        //回到主线程显示图片
        dispatch_async(dispatch_get_main_queue(), ^{
            //4.将新图片显示出来

            self.imageView.image = image;
        });

    });

}

5.延时(补充)

- (void)delay {
    //延时
    NSLog(@"______");
    [self performSelector:@selector(run) withObject:nil afterDelay:2.0];
}

- (void)run {
    NSLog(@"end");
}
时间: 2024-08-29 02:34:39

GCD的相关函数使用的相关文章

iOS中GCD的使用小结

本篇博客共分以下几个模块来介绍GCD的相关内容: 多线程相关概念 多线程编程技术的优缺点比较? GCD中的三种队列类型 The main queue(主线程串行队列) Global queue(全局并发队列) Custom queue (自定义队列) Group queue (队列组) GCD中一些系统提供的常用dispatch方法 多线程相关概念 进程与线程 进程概念: 进程是程序在计算机上的一次执行活动,打开一个app,就开启了一个进程,可包含多个线程. 线程概念: 独立执行的代码段,一个线

GCD的使用总结

什么是多线程? 计算机在运行一段程序的时候,会把该程序的CPU命令列配置到内存中,然后按照顺序一个一个执行命令列,这样1个CPU执行的CPU命令列为一条无分叉路径就是线程. 而有多条这样的执行指令列的路径存在时即为多线程. iOS实现多线程有4种方法: pthreads NSThread GCD NSOperation & NSOperationQueuef   这里我们主要讲GCD   一.Dispatch Queue和线程的关系 什么是Dispatch Queue? 如其名称,是执行处理的等

dutacm.club 1094: 等差区间(RMQ区间最大、最小值,区间GCD)

1094: 等差区间 Time Limit:5000/3000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)Total Submissions:655   Accepted:54 [Submit][Status][Discuss] Description 已知一个长度为 n 的数组 a[1],a[2],-,a[n],我们进行 q 次询问,每次询问区间 a[l],a[l+1],-,a[r?1],a[r] ,数字从小到大

iOS GCD中级篇 - dispatch_group的理解及使用

前文我们讲了GCD基础篇,以及同步.异步,并发.并行几个概率的理解. 参考链接: iOS GCD基础篇 - 同步.异步,并发.并行的理解 现在讲一下dispatch_group的概念以及几种场景下的使用 1.关于dispatch_group 把一组任务提交到队列中,这些队列可以不相关,然后监听这组任务完成的事件. 最常见的几个方法: 1.dispatch_group_create创建一个调度任务组 2.dispatch_group_async 把一个任务异步提交到任务组里 3.dispatch_

转 GCD

GCD 深入理解:第一部分 本文翻译自 http://www.raywenderlich.com/60749/grand-central-dispatch-in-depth-part-1 原作者:Derek Selander 译者:@nixzhu 虽然 GCD 已经出现过一段时间了,但不是每个人都明了其主要内容.这是可以理解的:并发一直很棘手,而 GCD 是基于 C 的 API ,它们就像一组尖锐的棱角戳进 Objective-C 的平滑世界.我们将分两个部分的教程来深入学习 GCD . 在这两

php数据库操作常用相关函数

MySQL访问函数都需要有相应的权限才能运行.常用的相关函数介绍如下: (1)integer mysql_connect(主机,用户名,口令); 此函数开始一个对指定主机上的MySQL数据库的连接.若该数据库位于一个不同地端口,则在主机名后加上冒号和端口号.所有参数均为可选的,缺省情况下分别对应为本地主机.用户正在执行的脚本名和空.主机可以是IP地址或域名. 在脚本执行结束时,连接被自动关闭,也可以用mysql_close提前关闭. (2)boolean mysql_create_db(数据库名

GCD多线程死锁总结

// //  ViewController.m //  多线程 // // #import "ViewController.h" @interface ViewController () @end @implementation ViewController /* >1 队列和线程的区别: 队列:是管理线程的,相当于线程池,能管理线程什么时候执行. 队列分为串行队列和并行队列 串行队列:队列中的线程按顺序执行(不会同时执行) 并行队列:队列中的线程会并发执行,可能会有一个疑问,队

GCD 常用操作

GCD多线程操作 1)用得最多的操作 //获取全局队列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //异步执行 dispatch_async(queue, ^{ //下载图片 dispatch_async(dispatch_get_main_queue(), ^{ //回到主线程更新UI }); }); ? 2)延时执行 1-调用NSObject方法 [Self

GCD

Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法. dispatch queue分成以下三种: 1)运行在主线程的Main queue,通过dispatch_get_main_queue获取. /*! * @function dispatch_get_main_queue * * @abstract * Returns the default queue that is bound to the main thread. * * @discussi