淺談GCD
1.什么是GCD
GCD
Grand Central Dispatch (GCD)是Apple開發(fā)的一個(gè)多核編程的較新的解決方法。它主要用于優(yōu)化應(yīng)用程序以支持多核處理器以及其他對(duì)稱多處理系統(tǒng)。它是一個(gè)在線程池模式的基礎(chǔ)上執(zhí)行的并行任務(wù)。在Mac OS X 10.6雪豹中首次推出,也可在IOS 4及以上版本使用。
優(yōu)點(diǎn):
·易用:比NSThread更加易用?;赽lock導(dǎo)致它簡(jiǎn)單的在不同的代碼域進(jìn)行傳遞。
·效率:GCD實(shí)現(xiàn)功能 輕量、優(yōu)雅,使得它在很多地方比之專門創(chuàng)建消耗資源的線程更 實(shí)用且快速
·性能:GCD自動(dòng)根據(jù)系統(tǒng)負(fù)載來增減線程數(shù)量,這就減少了上下文切換以及增加了計(jì) 算效率
·安全:無需加鎖或其他同步機(jī)制
2.GCD的使用
創(chuàng)建隊(duì)列
/***********************創(chuàng)建隊(duì)列***********************/
//1.串行隊(duì)列:
dispatch_queue_t que1 = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
//2.并發(fā)隊(duì)列創(chuàng)建
dispatch_queue_t que2 = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);
//3.主隊(duì)列(串行)
dispatch_queue_t mainQqueue = dispatch_get_main_queue();
//4.全局隊(duì)列(并發(fā))
//第一個(gè)0 是優(yōu)先級(jí),可以自行設(shè)置,第二個(gè)還沒有開發(fā)使用,暫時(shí)填0
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(0, 0);
添加隊(duì)列
/***********************添加隊(duì)列到任務(wù)***********************/
//dispatch_async 提交一個(gè)異步執(zhí)行的 block塊到隊(duì)列里面并且直接返回,不用等待block 被調(diào)用
//提交一個(gè)異步執(zhí)行的block塊,不用等待調(diào)用
dispatch_async(que1, ^{
NSLog(@"呵呵");
});
//dispatch_sync 提交一個(gè)同步的block到隊(duì)列中等待,直到block執(zhí)行完成。在主線程里添加主隊(duì)列容易造成死鎖
//例如: 相當(dāng)于 ---->NSLog(@"hehe");------>dispatch_sync
dispatch_sync(mainQqueue, ^{
NSLog(@"hehe");
});
//死鎖的原因是NSLog(@"hehe")任務(wù)等待dispatch_sync執(zhí)行完,dispatch_sync又需要執(zhí)行完NSLog(@"hehe")任務(wù)這個(gè)任務(wù),因?yàn)橹麝?duì)列是串行的,造成了阻塞。

添加到隊(duì)列.png
隊(duì)列的一些用法
/***********************隊(duì)列的用法***********************/
//dispatch_once實(shí)現(xiàn)單例模式
[UIApplication sharedApplication];//app的對(duì)象
[NSNotificationCenter defaultCenter];//通知中心對(duì)象
[UIDevice currentDevice];//當(dāng)前的設(shè)備
[NSUserDefaults standardUserDefaults]; //數(shù)據(jù)儲(chǔ)存
//dispatch_group創(chuàng)建一個(gè)分組,監(jiān)聽隊(duì)列中的任務(wù)。
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t groupQueue = dispatch_get_global_queue(0, 0);
//注意:這里是沒有先后順序的
dispatch_group_async(group, groupQueue, ^{
NSLog(@"1-天地不仁");
});
dispatch_group_async(group, groupQueue, ^{
NSLog(@"2-以萬物為芻狗");
});
dispatch_group_async(group, groupQueue, ^{
NSLog(@"3-圣人不仁");
});
dispatch_group_async(group, groupQueue, ^{
NSLog(@"4-以百姓為芻狗");
});
//結(jié)束之后會(huì)發(fā)送一個(gè)通知,有順序
dispatch_group_notify(group, groupQueue, ^{
NSLog(@"道德經(jīng)-老子");
});
//在未來設(shè)置一個(gè)時(shí)間點(diǎn)
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 5);
/*
DISPATCH_TIME_NOW 現(xiàn)在的時(shí)間點(diǎn)
NSEC_PER_SEC 秒
time 在未來五秒后
*/
//意思就是在未來的某一時(shí)刻(5s后)group會(huì)檢查任務(wù)的執(zhí)行程度。
long result = dispatch_group_wait(group, time);
/*PS:
* Returns zero on success (all blocks associated with the group completed
* within the specified timeout) or non-zero on error (i.e. timed out).
大意就是返回0就是成功了,不是0就是錯(cuò)誤的。
*/
if (result == 0) {
NSLog(@"任務(wù)執(zhí)行成功");
}else{
NSLog(@"任務(wù)執(zhí)行失敗");
}

組.png
快速高效的遍歷。
注意觀察輸出一萬次的時(shí)間
//apply迭代
NSMutableArray *array = [NSMutableArray arrayWithCapacity:10000];
for (int i = 0; i<10000; i++) {
[array addObject:[NSNumber numberWithInt:i]];
}
//dispatch_apply能過實(shí)現(xiàn)一個(gè)高性能的循環(huán)迭代
//dispatch_apply 會(huì)阻塞當(dāng)前線程,所以放在后臺(tái)線程中
/*
size_t iterations:迭代次數(shù)
queue:迭代的隊(duì)列
^(size_t) {
code
}:迭代過程匯總每次要做的事情
^(size_t i):迭代的變量,記得要自己添加。
*/
//使用迭代進(jìn)行輸出,效率是在主線程中的好幾倍。
dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_apply(array.count, dispatch_get_global_queue(0, 0), ^(size_t i) {
NSLog(@"%d",[array[i] intValue]);
});
});

迭代.png

迭代2.png
精確定時(shí)器的運(yùn)用:
//runLoop使一個(gè)線程處于運(yùn)行狀態(tài),不會(huì)被銷毀。
//最后在runLoop的基礎(chǔ)上介紹一下精確的定時(shí)器。
_index = 0;
_count = 0;
//屏幕刷新率是60HZ
//即1/60秒調(diào)用一次
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(timeAction)];
[link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
//CADisplayLink 不受其他線程的影響
long long j =0;
for (long i =0; i<1000000000; i++) {
j+=i;
}
}
- (void)timeAction{
_count ++;
if (_count == 60) {
NSLog(@"_index = %d",_index);
_index ++;
_count = 0;
}
}

精確定時(shí)器.png