iOS中 GCD-Grand Central Dispath 多線程 UI_21
來源:程序員人生 發布時間:2016-04-25 13:26:57 閱讀次數:2544次
GCD:Grand Central Dispath "牛逼的中樞調度器";是純C語言編寫的,提供了很多比較強大的函數
GCD:優勢
1.目前是蘋果主推的線程管理方式
2.它會自動的利用更多的CPU資源(雙核,4核)
3.它會自動的管理線程的生命周期(線程的創建/調度/燒毀);
4.程序員只需要告知GCD自己想要履行的哪些任務,不需要寫1行線程管理的代碼
#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;//第1個圖片
@property (retain, nonatomic) IBOutlet UIImageView *secondView;//第2個圖片
@property(nonatomic,retain)NSMutableArray *dataSource;//存儲要求下來的數據
@end
@implementation ViewController
//懶加載
- (NSMutableArray *)dataSource{
if (_dataSource == nil) {
self.dataSource = [NSMutableArray arrayWithCapacity:0];
}
return [[_dataSource retain]autorelease];
}
串行隊列:(線程同步)添加到這個隊列的任務1個接1個的履行(1個任務完成,才再去完成另外一個任務)
- (IBAction)handleSerialQueue:(UIButton *)sender {
//獲得系統串行隊列
// (1)向系統的創建的串行隊列中添加異步任務,還是在主線程中完成;
// (2)向系統創建的串行隊列中添加同步任務,會造成線程死鎖,致使其他人沒法履行;
dispatch_queue_t queue1 = dispatch_get_main_queue();
//01:隊列的唯1標識,采取反域名情勢
//02:隊列的屬性類型,也就是標識這個隊列是串行隊列還是并行隊列
// (1)自己創建的串行隊列中添加異步任務是在子線程中完成任務;
// (2)自己創建的串行隊列中添加同步任務是在主線程中完成任務;
dispatch_queue_t queue2 = dispatch_queue_create("com.xcqnzf.xuchang", DISPATCH_QUEUE_SERIAL);
/*
//異步任務
//第1個參數:任務添加到隊列名稱
//第2個參數: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.自己創建并行隊列 (1般不自己創建并行隊列,系統的并行隊列已夠用了)
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.分組隊列:把多個任務添加到1個分組中履行,此時會在所有的任務完成后會自動發1個通
知,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);
}
只履行1次
- (IBAction)handleOnce:(UIButton *)sender {
static dispatch_once_t oneToken ;
//
dispatch_once(&oneToken, ^{
NSLog(@"有本事讓我走兩次");
});
}
這里需要寫1個單例
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);
});
}
延遲任務 1個任務要履行的時候先等上1段時間再做
- (IBAction)handlePing:(UIButton *)sender {
//創建1個延遲任務
//01. DISPATCH_TIME_NOW 表示從當前時間開始
//02. 表示過量少秒才去履行任務
//03. 串行的主隊列
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"延遲任務在主線程中履行");
});
}
//釋放
- (void)dealloc {
[_FirstView release];
[_secondView release];
self.dataSource = nil;
[super dealloc];
}
分組隊列效果:
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈