GCD的连锁函数使用,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

效果正是开启八个线程同期做到有些事,举个例子同时下载多张图片

威尼斯城真人赌钱网站 1//一般的做法

  • (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(@”剪切成功”); }); } View
    Code

    //使用高效迭代进行剪切

    • (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

与栅栏函数有同等的指标,为了操纵十二线程的实践种种

比如说下载两张图片之后,再将这两个合併成新的图纸并出示。

不能不得先下完之后技艺集合吧!(顺序难题,十六线程是不可控的)

威尼斯城真人赌钱网站 2//队列组

  • (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, ^{ //落成下载 NSU卡宴L
    *url = [NSURL
    URLWithString:@”];
    NSData *data = [NSData dataWithContentsOfURL:url]; //生成图片
    self.img1 = [UIImage imageWithData:data]; }); //2.下载图片2
    dispatch_group_async(group, queue, ^{ //实现下载 NSUKoleosL *url = [NSURL
    URLWithString:@”];
    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; }); }); } View Code

 

5.延时(补充)

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

- (void)run {
    NSLog(@"end");
}

 

GCD
是iOS二十多线程达成方案之一,非平时用
意大利语翻译过来就是高大的中枢调解器,也许有人戏称为是牛逼的…

知识点一

栅栏函数

1.基本概念

1.gcd栅栏函数

威尼斯城真人赌钱网站 3

1.栅栏函数

GCD中还可能有个用来奉行职分的函数

1.栅栏函数能够用来支配任务的执行顺序

1.1 进程

2.gcd快速迭代方法(dispatch_apply)同for循环做相比。

威尼斯城真人赌钱网站 4

案例:将文件夹from中的内容剪切到文件夹to中。

//案例(gcd火速迭代)创造子线程的办法

-(void)movefilegcd{

//获得文件目录

NSString* from =@”/Users/wuyanan/Desktop/from”;

//得到指标文件路线

NSString* to =@”/Users/wuyanan/Desktop/to”;

//获得目录下的兼具文件(重返的是数组)

NSArray* subPath =
[[NSFileManagerdefaultManager]subpathsAtPath:from];

NSLog(@”wenjian—-%@”,subPath);

//遍历全体文件,推行剪切操作

NSIntegercount =[subPathcount];

dispatch_apply(count,dispatch_get_global_queue(0,0),
^(size_tindex) {

//4.1拼凑文件的全路线

//拼接的时候会自动抬高/

NSString*fullpath
=[fromstringByAppendingPathComponent:subPath[index]];

NSString* tofullpath
=[tostringByAppendingPathComponent:subPath[index]];

NSLog(@”wenjian—-%@”,fullpath);

//4.2试行剪切操作

/*

先是个参数:源文件路线,要分开的文件的地方

第1个参数:指标文件路线,文件应当被平放的职位

其多个参数:

*/

[[NSFileManagerdefaultManager]moveItemAtPath:fullpathtoPath:tofullpatherror:nil];

});

}

注意点:

威尼斯城真人赌钱网站 5

dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t
block);

dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t
block);

经过是指在系统中正在运维的贰个应用程序。各类进度之间是独立的,各类进度均运行在其专项使用且受保证的内部存款和储蓄器空间内。

3.gcd队列组

gcd的队列组也能够决定顺序。队列组里面包车型客车队列职分的实践情形。当职责都成功的时候发送布告。

威尼斯城真人赌钱网站 6

gcd队列组

案例2:下载两张图片,下载完结后合成一张图纸

-(void)group3

{

/*

1.下载图片1开子线程

2.下载图片2开子线程

3.合成图片并展现图片开子线程

*/

//-1.得到队列组

dispatch_group_tgroup =dispatch_group_create();

//0.拿走并发队列

dispatch_queue_tqueue =dispatch_get_global_queue(0,0);

// 1.下载图片1开子线程

dispatch_group_async(group, queue,^{

NSLog(@”download1—%@”,[NSThreadcurrentThread]);

//1.1确定url

NSURL*url =
[NSURLURLWithString:@”];

//1.2下载二进制数据

NSData*imageData = [NSDatadataWithContentsOfURL:url];

//1.3转换图片

self.image1= [UIImageimageWithData:imageData];

});

// 2.下载图片2开子线程

dispatch_group_async(group, queue,^{

NSLog(@”download2—%@”,[NSThreadcurrentThread]);

//2.1确定url

NSURL*url =
[NSURLURLWithString:@”];

//2.2下载二进制数据

NSData*imageData = [NSDatadataWithContentsOfURL:url];

//2.3转移图片

self.image2= [UIImageimageWithData:imageData];

});

//3.统一图片

//主线程中施行

dispatch_group_notify(group,dispatch_get_main_queue(), ^{

NSLog(@”combie—%@”,[NSThreadcurrentThread]);

//3.1创设图形上下文

UIGraphicsBeginImageContext(CGSizeMake(200,200));

//3.2画图1

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

self.image1=nil;

//3.3画图2

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

self.image2=nil;

//3.4基于上下文获得一张图片

UIImage*image =UIGraphicsGetImageFromCurrentImageContext();

//3.5关门上下文

UIGraphicsEndImageContext();

//3.6更新UI

//dispatch_async(dispatch_get_main_queue(), ^{

NSLog(@”UI—-%@”,[NSThreadcurrentThread]);

self.imageView.image= image;

//});

});

}

使用creat函数创造的出现队列和大局队列的重点不同:

1.利用全局并发队列在一切应用程序中本人是暗许存在的,何况对应该高优先级、暗中同意优先级,低优先级和后台优先级共计八个并发队列。大家只是选取贰个一向拿来用。何况create函数是实际的从头开始创设贰个行列。

2.在iOS6事先,在gcd中凡是使用了饱含create和retain的函数,末了都亟需做贰回release操作。而主队列和全局并发队列没有必要我们手动release。iOS6过后,无需手动管理。

在选拔栅栏函数的时候,苹果官方规定只有栅栏函数独有在和应用creat函数本人创造的并发队列一同使用的时候才使得

在头里的天职施行几人数后它才施行,并且它背后的职责等它施行到位之后才会实践

2.留神:只可以利用全局并发队列

1.2 线程

4.GCD补充

gcd开启线程的三种方法相比较:

威尼斯城真人赌钱网站 7

以此queue不能是大局的面世队列

贰回性函数

(1)基本概念

知识点二

使用dispatch_once函数能有限支撑某段代码在程序运转进度中只被施行1次

1个进程要想实行任务,必须得有线程(每1个进度至少要有1条线程),线程是进程的中坚进行单元,贰个进度(程序)的全体职责都在线程中奉行。

延时执行

static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{

    //只进行1次的代码(这其间暗中同意是线程安全的)

});

(2)线程的串行

iOS常见的延时实践办法

1.本性:在一切程序运营进程中,贰次性函数里面包车型大巴代码只会实行二遍

1个线程中职务的实践是串行的,假使要在1个线程中推行四个职责,那么只能一个多个地按顺序实行这一个职分。也等于说,在同一时间内,1个线程只可以实行1个任务。

1.调用NSObject方法

2.专注:说明:不可能把二次性代码放到懒加载中

1.3 多线程

[self performSelector:@selector(run)  WithObject:nil afterDelay:2.0];

推迟试行

(1)基本概念

//2秒后再延迟self 的 run方法

1.调用NSObject的方法

即1个进度中能够张开多条线程,每条线程能够相互(同一时间)实践不一的义务。

2.使用GCD函数

[self performSelector:@selector(run) withObject:nil afterDelay:2.0]

(2)线程的互动

dispatch_ater(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2.0 *
NSEC_PER_SEC)),dispatch_get_main_queue(),^{

2.使用NSTimer

并行即同一时间实施。比方同不时间拉开3条线程分别下载3个公文(分别是文件A、文件B、文件C。

//2秒后再实行这里的代码

[NSTimer scheduledTimerWithTimeInterval:2.0 target:self
selector:@selector(test) userInfo:nil repeats:NO];

(3)八线程并发实践的法则

})

3.使用GCD函数里面包车型地铁dispatch_after

在同期里,CPU只好管理1条线程,独有1条线程在做事(推行)。多线程并发(同期)实践,其实是CPU急速地在多条线程之间调整(切换),固然CPU调解线程的时刻丰盛快,就导致了八线程并发实施的假象

3.使用NSTimer

dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2.0*
NSEC_PER_SEC)),

dispatch_get_main_queue(),^{

    //

2秒后实行这里的代码…

});

(4)四线程优劣势

[NSTimer scheduledTimerWithTimerInterval:2.0 target:self
selector:@selector(test) userInfo:nil repeats:NO];

高速迭代

优点

知识点三

使用dispatch_apply函数能展开高效迭代遍历

1)能方便巩固程序的实践成效。

一回性代码

dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t
index){

    //实行10次代码,index顺序不分明

});

2)能确切加强能源利用率(CPU、内部存款和储蓄器利用率)

使用dispatch_once函数能担保某段代码在程序运转进程中只进行1次

①了解FO冠道循环的遍历方式

缺点

static dispatch_once_t onceToken;

②应用for循环完毕一个文书剪切案例

1)开启线程须求占用一定的内部存款和储蓄器空间(暗中同意情形下,主线程占用1M,子线程占用512KB),如果张开多量的线程,会占有多量的内存空间,减少程序的质量。

dispatch_once(&onceToken,^{

③利用便捷迭代达成文件剪切案例

2)线程更加多,CPU在调节线程上的支付就越大。

//只可以实施1次的代码(这里面私下认可是线程安全的)


3)程序设计特别纵横交叉:比如线程之间的通讯、二十三十二线程的数额分享

NSLog(@”————-run”);

-(void)applay

{

//成立三个油不过生队列

//    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

//      dispatch_queue_t queue = dispatch_get_main_queue(); 
//不可行

//    dispatch_queue_t queue = dispatch_queue_create(“123”,
DISPATCH_QUEUE_SERIAL);

    dispatch_queue_t queue = dispatch_queue_create(“123”,
DISPATCH_QUEUE_CONCURRENT);

    //获得有个别文件夹下边的持有文件

    NSFileManager *manager = [NSFileManager defaultManager];

    NSString *from  = @”/Users/文顶顶/Desktop/from”;

    NSString *to = @”/Users/文顶顶/Desktop/to”;

  NSArray *array =  [manager subpathsAtPath:from];

    dispatch_apply(array.count, queue, ^(size_t index) {

//        NSLog(@”%zd—%@”,index,[NSThread currentThread]);

        //拼接文件夹上边各种文件的全路径

        NSString *subpath = array[index];

        NSString *fullPath = [from
stringByAppendingPathComponent:subpath];

        //拼接该文件应该剪切到哪些地点

        NSString *toFullPath = [to
stringByAppendingPathComponent:subpath];

        //实践剪切操作

        [manager moveItemAtPath:fullPath toPath:toFullPath
error:nil];

        NSLog(@”%@–%@–%@”,fullPath,toFullPath,[NSThread
currentThread]);

    });

}

1.4 八线程在iOS开采中的应用

});


(1)主线程

知识点四

队列组的运用

1)三个iOS程序运维后,私下认可会开启1条线程,称为“主线程”或“UI线程”。

高效迭代

首先:分别异步试行2个耗费时间的操作

2)功能。刷新显示UI,管理UI事件。

使用dispatch_apply函数能开始展览火速迭代遍历

其次:等2个异步操作都实行完结后,再回来主线程实行操作

(2)使用注意

dispatch_apply(10,queue,^(size_t index){

①用加入景:下载两张图片,拼接图片后到主线程中刷新

1)不要将耗费时间操作放到主线程中去管理,会卡住线程。

//试行10回代码,index顺序不分明

 1.下载图片1 开子线程

1.5 iOS中三十二线程的贯彻方案

NSLog(@”—————%ld——–%@”,index,[NSThread currentThread]);

 2.下载图片2 开子线程

(1)pthread

});

 3.合成图片并展示图片 开子线程

01 特点:

知识点五

②应用栅栏函数完毕

(1)一套通用的四线程API

队列组

思路:举个例子把下载操作开垦三个子线程,等待下载停止以往调用栅栏函数dispatch_barrier_async,等待施行达成,再去绘图

(2)适用于Unix\Linux\Windows等系统

有这般种供给

③运用队列组来实现须求

(3)跨平台\可移植

首先,分别异步执行2个耗费时间的操作

具体步骤可以参照如下:

(4)使用难度大

相关文章