版權(quán)聲明:本文為博主原創(chuàng)文章车伞,未經(jīng)博主允許不得轉(zhuǎn)載。
GCD:Grand Central Dispath "牛逼的中樞調(diào)度器";是純C語(yǔ)言編寫(xiě)的,提供了很多比較強(qiáng)大的函數(shù).
GCD:優(yōu)勢(shì)
1.目前是蘋(píng)果主推的線(xiàn)程管理方式
2.它會(huì)自動(dòng)的利用更多的CPU資源(雙核,四核)
3.它會(huì)自動(dòng)的管理線(xiàn)程的生命周期(線(xiàn)程的創(chuàng)建/調(diào)度/銷(xiāo)毀);
4.程序員只需要告訴GCD自己想要執(zhí)行的哪些任務(wù),不需要寫(xiě)一行線(xiàn)程管理的代碼
#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;//第一個(gè)圖片
@property (retain, nonatomic) IBOutlet UIImageView *secondView;//第二個(gè)圖片
@property(nonatomic,retain)NSMutableArray *dataSource;//存儲(chǔ)請(qǐng)求下來(lái)的數(shù)據(jù)
@end
@implementation ViewController
//懶加載
- (NSMutableArray *)dataSource
{
if (_dataSource == nil)
{
self.dataSource = [NSMutableArray arrayWithCapacity:0];
}
return [[_dataSource retain]autorelease];
}```
1.串行隊(duì)列:(線(xiàn)程同步)添加到這個(gè)隊(duì)列的任務(wù)一個(gè)接一個(gè)的執(zhí)行(一個(gè)任務(wù)完成,才再去完成另一個(gè)任務(wù))
- (IBAction)handleSerialQueue:(UIButton *)sender
{
//獲取系統(tǒng)串行隊(duì)列
// (1)向系統(tǒng)的創(chuàng)建的串行隊(duì)列中添加異步任務(wù),還是在主線(xiàn)程中完成;
// (2)向系統(tǒng)創(chuàng)建的串行隊(duì)列中添加同步任務(wù),會(huì)造成線(xiàn)程死鎖,導(dǎo)致其他人無(wú)法執(zhí)行;
dispatch_queue_t queue1 = dispatch_get_main_queue();
//01:隊(duì)列的唯一標(biāo)識(shí),采用反域名形式
//02:隊(duì)列的屬性類(lèi)型,也就是標(biāo)識(shí)這個(gè)隊(duì)列是串行隊(duì)列還是并行隊(duì)列
// (1)自己創(chuàng)建的串行隊(duì)列中添加異步任務(wù)是在子線(xiàn)程中完成任務(wù);
// (2)自己創(chuàng)建的串行隊(duì)列中添加同步任務(wù)是在主線(xiàn)程中完成任務(wù);
dispatch_queue_t queue2 = dispatch_queue_create("com.xcqnzf.xuchang", DISPATCH_QUEUE_SERIAL);
/*
//異步任務(wù)
//第一個(gè)參數(shù):任務(wù)添加到隊(duì)列名稱(chēng)
//第二個(gè)參數(shù):block執(zhí)行任務(wù)內(nèi)容
dispatch_async(queue2, ^{
NSLog(@"任務(wù)1 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
});
dispatch_async(queue2, ^{
NSLog(@"任務(wù)2 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
});
dispatch_async(queue2, ^{
NSLog(@"任務(wù)3 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
});
//釋放掉自己的創(chuàng)建的隊(duì)列,出現(xiàn)create就要釋放
dispatch_release(queue2);
*/
//同步任務(wù)
dispatch_sync(queue2, ^{
NSLog(@"任務(wù)1 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
});
dispatch_sync(queue2, ^{
NSLog(@"任務(wù)2 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
});
dispatch_sync(queue2, ^{
NSLog(@"任務(wù)3 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
});
// 總結(jié):同步任務(wù):不管在哪一個(gè)隊(duì)列中都是主線(xiàn)程中執(zhí)行,但是不能將其添加到系統(tǒng)自帶的串行隊(duì)列中;
// 異步任務(wù):在自己創(chuàng)建的串行隊(duì)列中,在子線(xiàn)程中執(zhí)行,如果是系統(tǒng)創(chuàng)建的隊(duì)列在主線(xiàn)程中執(zhí)行;
}```
2.并行隊(duì)列 (線(xiàn)程并發(fā)) 添加到此隊(duì)列的任務(wù)同時(shí)執(zhí)行 假象.
- (IBAction)handleConcurrentQueue:(UIButton *)sender
{
//1.獲取系統(tǒng)自帶的并行隊(duì)列
//01.隊(duì)列的優(yōu)先級(jí)
//02.預(yù)留參數(shù) 給0
dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//2.自己創(chuàng)建并行隊(duì)列 (一般不自己創(chuàng)建并行隊(duì)列,系統(tǒng)的并行隊(duì)列已經(jīng)夠用了)
dispatch_queue_t queue2 = dispatch_queue_create("com.xcqnzf.xuchang", DISPATCH_QUEUE_CONCURRENT);
//同步任務(wù)
dispatch_sync(queue1, ^{
NSLog(@"同步任務(wù)%@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
});
//異步任務(wù)
dispatch_async(queue2, ^{
NSLog(@"任務(wù)1%@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
});
dispatch_async(queue2, ^{
NSLog(@"任務(wù)2%@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
});
dispatch_async(queue2, ^{
NSLog(@"任務(wù)3%@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
//線(xiàn)程間的通信
//由子線(xiàn)程回到主線(xiàn)程
//獲取系統(tǒng)的串行隊(duì)列
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"我回到主線(xiàn)程了");
});
});
//釋放出現(xiàn)create就要釋放
dispatch_release(queue2);
}```
3.分組隊(duì)列:把多個(gè)任務(wù)添加到一個(gè)分組中執(zhí)行,此時(shí)會(huì)在所有的任務(wù)完成后會(huì)自動(dòng)發(fā)一個(gè)通
知,dispatch_group_notifity接收這個(gè)消息,然后在所有任務(wù)完成之后處理.
- (IBAction)handleGroupQueue:(UIButton *)sender {
//1.創(chuàng)建并行隊(duì)列,并執(zhí)行任務(wù)
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
__block typeof(self)weakSelf = self;
//創(chuàng)建分組異步同步任務(wù)
dispatch_group_t group = dispatch_group_create();
//01.分組名
//02.要添加的隊(duì)列名
//03.要執(zhí)行的任務(wù)
dispatch_group_async(group, queue, ^{
NSURL *urlString = [NSURL URLWithString:kURLString1];
NSData *data1 = [NSData dataWithContentsOfURL:urlString];
//使用數(shù)組存放請(qǐng)求下來(lái)的數(shù)據(jù)
[weakSelf.dataSource addObject:data1];
});
dispatch_group_async(group, queue, ^{
NSURL *url = [NSURL URLWithString:kURLString2];
NSData *data2 = [NSData dataWithContentsOfURL:url];
[weakSelf.dataSource addObject:data2];
});
//分組中的任務(wù)都完成后會(huì)自動(dòng)觸發(fā)下面的方法
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.障礙隊(duì)列
- (IBAction)handleBarrierQueue:(UIButton *)sender {
//1.使用障礙隊(duì)列只能使用自己創(chuàng)建的并列隊(duì)列,不能使用系統(tǒng)的并行隊(duì)列
dispatch_queue_t queue = dispatch_queue_create("com.xcqnzf.xuchang", DISPATCH_QUEUE_CONCURRENT);
//2.往并行隊(duì)列中添加任務(wù)
dispatch_async(queue, ^{
NSLog(@"A寫(xiě)入文件");
});
dispatch_async(queue, ^{
NSLog(@"B寫(xiě)入文件");
});
dispatch_async(queue, ^{
NSLog(@"C寫(xiě)入文件");
});
//添加障礙,間隔寫(xiě)入和讀取的任務(wù),障礙任務(wù)之前的任務(wù)都完成了才能繼續(xù)完成障礙任務(wù)后面的任務(wù)
dispatch_barrier_async(queue, ^{
NSLog(@"我是障礙任務(wù),讀取的任務(wù)先等會(huì)");
});
dispatch_async(queue, ^{
NSLog(@"D讀取文件");
});
dispatch_async(queue, ^{
NSLog(@"D讀取文件");
});
dispatch_async(queue, ^{
NSLog(@"E讀取文件");
});
//3.釋放
dispatch_release(queue);
}
只執(zhí)行一次
- (IBAction)handleOnce:(UIButton *)sender {
static dispatch_once_t oneToken ;
//
dispatch_once(&oneToken, ^{
NSLog(@"有能耐讓我走兩次");
});
}
這里需要寫(xiě)一個(gè)單例
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
重復(fù)任務(wù)
- (IBAction)handleRepeat:(UIButton *)sender {
//1.獲取系統(tǒng)的并行隊(duì)列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//2.向隊(duì)列中添加重復(fù)任務(wù)
//01.任務(wù)重復(fù)的次數(shù)
//02.任務(wù)添加到的隊(duì)列名稱(chēng)
//03.當(dāng)前是第幾次重復(fù)這個(gè)任務(wù)
dispatch_apply(10, queue, ^(size_t times) {
NSLog(@"我要吃爆米花,這是我第%ld吃",times);
});
}
延遲任務(wù) 一個(gè)任務(wù)要執(zhí)行的時(shí)候先等上一段時(shí)間再做
- (IBAction)handlePing:(UIButton *)sender { //創(chuàng)建一個(gè)延遲任務(wù)
//01. DISPATCH_TIME_NOW 表示從當(dāng)前時(shí)間開(kāi)始
//02. 表示過(guò)多少秒才去執(zhí)行任務(wù)
//03. 串行的主隊(duì)列
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(55 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"延遲任務(wù)在主線(xiàn)程中執(zhí)行"); });
}```