多線程
GCD
? 全稱是Grand Central Dispatch
? 純C語言岸霹,提供了非常多強(qiáng)大的函數(shù)
執(zhí)行任務(wù)的方式
同步的方式
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
queue:隊(duì)列
block:任務(wù)
異步的方式
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
隊(duì)列類型
可以分為兩大類
1.并發(fā)隊(duì)列 ? Concurrent Dispatch Queue
? 可以讓多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行(自動(dòng)開啟多個(gè)線程同時(shí)執(zhí)行任務(wù))
? 并發(fā)功能只有在異步(dispatch_async)函數(shù)下才有效
2.串行隊(duì)列 ? Serial Dispatch Queue
? 讓任務(wù)一個(gè)接著一個(gè)地執(zhí)行(一個(gè)任務(wù)執(zhí)行完畢后摇展,再執(zhí)行下一個(gè)任務(wù))
總結(jié)
? 同步和異步?jīng)Q定了要不要開啟新的線程
? 同步:在當(dāng)前線程中執(zhí)行任務(wù)岩梳,不具備開啟新線程的能力
? 異步:在新的線程中執(zhí)行任務(wù),具備開啟新線程的能力
? 并發(fā)和串行決定了任務(wù)的執(zhí)行方式
? 并發(fā):多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行
? 串行:一個(gè)任務(wù)執(zhí)行完畢后,再執(zhí)行下一個(gè)任務(wù)
全局隊(duì)列
本質(zhì)就是并發(fā)隊(duì)列
dispatch_get_global_queue(0,0);
全局隊(duì)列和并發(fā)隊(duì)列的區(qū)別
? 并發(fā)隊(duì)列有名稱秒赤,可以跟蹤錯(cuò)誤妆档,全局隊(duì)列沒有
? 在ARC中不需要考慮釋放內(nèi)存萍悴, dispatch_release(q);不允許調(diào)用岩齿。在MRC中需要手動(dòng)釋放內(nèi)存太颤,
并發(fā)隊(duì)列是create創(chuàng)建出來的 在MRC中見到create就要release,全局隊(duì)列不需要release(只有一個(gè))
? 一般我們使用全局隊(duì)列
主隊(duì)列
主隊(duì)列,異步任務(wù)
? 不開線程盹沈,同步執(zhí)行
? 主隊(duì)列特點(diǎn):如果主線程正在執(zhí)行代碼暫時(shí)不調(diào)度任務(wù)龄章,等主線程執(zhí)行結(jié)束后在執(zhí)行任務(wù)
? 主隊(duì)列又叫 全局串行隊(duì)列
主隊(duì)列,同步任務(wù)
? 程序執(zhí)行不出來(死鎖)
? 死鎖的原因,當(dāng)程序執(zhí)行到下面這段代碼的時(shí)候
? 主隊(duì)列:如果主線程正在執(zhí)行代碼乞封,就不調(diào)度任務(wù)
? 同步執(zhí)行:如果第一個(gè)任務(wù)沒有執(zhí)行做裙,就繼續(xù)等待第一個(gè)任務(wù)執(zhí)行完成,再執(zhí)行下一個(gè)任務(wù)此時(shí)互相等待肃晚,程序無法往下執(zhí)行(死鎖)
dispatch_sync(q, ^{
NSLog(@"%@ -- %d",[NSThread currentThread],i);
});
死鎖解決方案
? (主隊(duì)列锚贱,同步執(zhí)行)放入異步執(zhí)行 解決死鎖
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"全局隊(duì)列,異步執(zhí)行 %@",[NSThread currentThread]);
//此時(shí)這行代碼 在子線程中運(yùn)行关串,同步執(zhí)行不用等待主線程執(zhí)行此同步執(zhí)行的任務(wù)
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"主隊(duì)列,同步執(zhí)行 %@",[NSThread currentThread]);
});
NSLog(@"==");
});
GCD其他操作
延時(shí)操作
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
(int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
});
? dispatch_after的定義
dispatch_after(dispatch_time_t when,
dispatch_queue_t queue,
dispatch_block_t block);
? dispatch_after的參數(shù)
參數(shù)1 dispatch_time_t when
多少納秒之后執(zhí)行
參數(shù)2 dispatch_queue_t queue
任務(wù)添加到那個(gè)隊(duì)列
參數(shù)3 dispatch_block_t block
要執(zhí)行的任務(wù)
Arc下的單例實(shí)現(xiàn)
static id _instancetype
+(instancetype)shardName{
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
_instancetype = [[self alloc]init]
});
return _instancetype;
}
調(diào)度組
? 有時(shí)候需要在多個(gè)異步任務(wù)都執(zhí)行完成之后繼續(xù)做某些事情拧廊,
比如下載歌曲,等所有的歌曲都下載完畢之后 轉(zhuǎn)到 主線程提示用戶
//1 全局隊(duì)列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//2 調(diào)度組
dispatch_group_t group = dispatch_group_create();
//3 添加任務(wù)
//把任務(wù)添加到隊(duì)列晋修,等任務(wù)執(zhí)行完成之后通知調(diào)度組
dispatch_group_async(group, queue, ^{
NSLog(@"歌曲1 %@",[NSThread currentThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"歌曲2 %@",[NSThread currentThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"歌曲3 %@",[NSThread currentThread]);
});
//4 所有任務(wù)都執(zhí)行完成后卦绣,獲得通知 (異步執(zhí)行)
//等調(diào)度組中隊(duì)列的任務(wù)完成后,把block添加到指定的隊(duì)列
// dispatch_group_notify(group, queue, ^{
// NSLog(@"okkkkkkk %@",[NSThread currentThread]);
// });
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
//更新UI控件飞蚓,提示用戶
NSLog(@"okkkkkkk %@",[NSThread currentThread]);
});
NSLog(@"over");
[TOC]