GCD

轉載自:http://www.lxweimin.com/p/4ac227e763fa

GCD

Grand Central Dispatch (GCD) 是 Apple 開發的一個多核編程的解決方法。該方法在 Mac OS X 10.6 雪豹中首次推出,并隨后被引入到了 iOS4.0 中。GCD 是一個替代諸如NSThread,NSOperationQueue,NSInvocationOperation等技術的很高效和強大的技術。

GCD 和 block 的配合使用,可以方便地進行多線程編程。

Clone

git clone https://github.com/KingComeFromChina/GCD.git

任務和隊列

1.任務分為同步任務和異步任務,隊列分為串行和并行

2.同步任務不會開線程,異步任務會開線程

- (void)sync_queue:(dispatch_queue_t)queue{

//同步任務

dispatch_sync(queue, ^{

NSLog(@"同步1 - %@",[NSThread currentThread]);

});

dispatch_sync(queue, ^{

NSLog(@"同步2 - %@",[NSThread currentThread]);

});

dispatch_sync(queue, ^{

NSLog(@"同步3 - %@",[NSThread currentThread]);

});

dispatch_sync(queue, ^{

NSLog(@"同步4 - %@",[NSThread currentThread]);

});

}

- (void)async_queue:(dispatch_queue_t)queue{

//異步任務

dispatch_async(queue, ^{

NSLog(@"異步1 - %@",[NSThread currentThread]);

});

dispatch_async(queue, ^{

NSLog(@"異步2 - %@",[NSThread currentThread]);

});

dispatch_async(queue, ^{

NSLog(@"異步3 - %@",[NSThread currentThread]);

});

dispatch_async(queue, ^{

NSLog(@"異步4 - %@",[NSThread currentThread]);

});

}

3.串行隊列一個一個的執行,并行隊列一起執行

同步任務

dispatch_sync(<#dispatch_queue_t? _Nonnull queue#>, <#^(void)block#>)

異步任務

dispatch_async(<#dispatch_queue_t? _Nonnull queue#>, <#^(void)block#>)

主隊列

dispatch_queue_t mainQueue = dispatch_get_main_queue();

全局并發隊列

dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

自定義串行隊列

dispatch_queue_t serialQueue = dispatch_queue_create("wanglei", NULL);

自定義并行隊列

dispatch_queue_t concurrentQueue = dispatch_queue_create("king", DISPATCH_QUEUE_CONCURRENT);

同步主線程會卡死,造成死循環

[self sync_queue:mainQueue];

異步主線程不會開線程,順序執行

[self async_queue:mainQueue];

同步全局并發不會開線程,順序執行

[self sync_queue:globalQueue];

異步全局并發會開線程,亂序執行

[self async_queue:globalQueue];

同步串行不會開線程,順序執行

[self sync_queue:serialQueue];

異步串行會開線程,順序執行

[self async_queue:serialQueue];

同步并行不會開線程,順序執行

[self sync_queue:concurrentQueue];

異步并行會開線程,亂序執行

[self async_queue:concurrentQueue];

線程間通信

#pragma mark - 線程間通訊

- (void)threadCommunication{

//主隊列

dispatch_queue_t mainQueue = dispatch_get_main_queue();

//全局并發隊列

dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(globalQueue, ^{

NSURL *url = [NSURL URLWithString:@""];

NSData *data = [[NSData alloc]initWithContentsOfURL:url];

NSLog(@"%@",[NSThread currentThread]);

dispatch_async(mainQueue, ^{

data;

//在這里刷新UI

NSLog(@"mainQueue -- %@",[NSThread currentThread]);

});

});

}

GCD創建單例

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

NSLog(@"只執行一次");

});

}

GCD創建分組任務

- (void)dispatch_group{

// 創建一個分組

dispatch_group_t group = dispatch_group_create();

// 全局隊列

dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

// 第一個參數: 任務所在的分組

// 第二個參數: 任務所在的隊列

dispatch_group_async(group, globalQueue, ^{

NSLog(@"分組任務1");

});

dispatch_group_async(group, globalQueue, ^{

NSLog(@"分組任務2");

});

// 當上面兩個任務都完成以后,會執行這個方法,我們在這里處理我們的需求

dispatch_group_notify(group, globalQueue, ^{

NSLog(@"上面分組任務完成后,才會執行");

});

}

GCD延遲操作

- (void)dosomethingByTime{

// 延遲加載函數

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

NSLog(@"延遲10s加載");

});

// 自定義并行隊列

dispatch_queue_t concurrentQueue = dispatch_queue_create("wanglei", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(concurrentQueue, ^{

NSLog(@"dispatch_async - 1-%@",[NSThread currentThread]);

});

dispatch_async(concurrentQueue, ^{

NSLog(@"dispatch_async - 2-%@",[NSThread currentThread]);

});

// dispatch_barrier_async 使用于并行環境下

// 使用dispatch_barrier_async添加的任務會在之前的block全部運行完畢之后,才會繼續執行。保證對非線程安全的對象進行正確的操作

// 運行完dispatch_barrier_async的block才會執行后面的任務

// dispatch_barrier_async所在的線程跟前一個任務是同一條線程

dispatch_barrier_async(concurrentQueue, ^{

NSLog(@"dispatch_barrier_async-%@",[NSThread currentThread]);

});

dispatch_barrier_async(concurrentQueue, ^{

NSLog(@"dispatch_barrier_async- 3 -%@",[NSThread currentThread]);

});

dispatch_barrier_async(concurrentQueue, ^{

NSLog(@"dispatch_barrier_async- 4 -%@",[NSThread currentThread]);

});

}

GCD下載圖片及合成

- (void)drawRectImage{

// 創建全局并發隊列

dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

// 異步下載

dispatch_async(globalQueue, ^{

// 下載第一張圖片

NSURL *url1 = [NSURL URLWithString:@"http://pic6.huitu.com/res/20130116/84481_20130116142820494200_1.jpg"];

NSData *data1 = [NSData dataWithContentsOfURL:url1];

UIImage *image1 = [UIImage imageWithData:data1];

// 下載第二張圖片

NSURL *url2 = [NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/c2cec3fdfc03924578c6cfe18394a4c27c1e25e8.jpg"];

NSData *data2 = [NSData dataWithContentsOfURL:url2];

UIImage *image2 = [UIImage imageWithData:data2];

// 合并圖片

// 開啟一個位圖上下文

UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0.0);

// 繪制第一張圖片

CGFloat image1Width = image1.size.width;

CGFloat image1Height = image1.size.height;

[image1 drawInRect:CGRectMake(0, 0, image1Width, image1Height)];

// 繪制第二張圖片

CGFloat image2Width = image2.size.width * 0.5;

CGFloat image2Height = image2.size.height * 0.5;

CGFloat image2Y = image1Height - image2Height;

[image2 drawInRect:CGRectMake(0, image2Y, image2Width, image2Height)];

// 得到上下文中的圖片

UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext();

// 結束上下文

UIGraphicsEndImageContext();

// 回到主線程顯示圖片

dispatch_queue_t mainQueue = dispatch_get_main_queue();

dispatch_async(mainQueue, ^{

self.imageView.image = fullImage;

});

});

}

GCD實現的驗證碼倒計時

- (void)btnClick{

[_btn setTitle:@"重發(60s)" forState:UIControlStateNormal];

__block int timeout=59; //倒計時時間

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);

dispatch_source_set_timer(_timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒執行

dispatch_source_set_event_handler(_timer, ^{

if(timeout<=0){ //倒計時結束,關閉

dispatch_source_cancel(_timer);

dispatch_async(dispatch_get_main_queue(), ^{

//設置界面的按鈕顯示 根據自己需求設置

self.btn.userInteractionEnabled = YES;

[self.btn setTitle:@"獲取驗證碼" forState:UIControlStateNormal];

});

}else{

int seconds = timeout % 60;

NSString *strTime = [NSString stringWithFormat:@"%.2d", seconds];

dispatch_async(dispatch_get_main_queue(), ^{

//設置界面的按鈕顯示 根據自己需求設置

[UIView beginAnimations:nil context:nil];

[UIView setAnimationDuration:1];

[self.btn setTitle:[NSString stringWithFormat:@"重發(%@秒)",strTime] forState:UIControlStateNormal];

[UIView commitAnimations];

self.btn.userInteractionEnabled = NO;

});

timeout--;

}

});

dispatch_resume(_timer);

}

效果圖

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?效果圖

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容