多線程 GCD

n多線程
GCD
 
n簡介
n什麼是GCD
p全稱是Grand Central Dispatch,可譯爲「牛逼的中樞調度器」
p純C語言,提供了很是多強大的函數
p
nGCD的優點
pGCD是蘋果公司爲多核的並行運算提出的解決方案
pGCD會自動利用更多的CPU內核(好比雙核、四核)
pGCD會自動管理線程的生命週期(建立線程、調度任務、銷燬線程)
p程序員只須要告訴GCD想要執行什麼任務,不須要編寫任何線程管理代碼
n任務和隊列
nGCD中有2個核心概念
p任務:執行什麼操做
p隊列:用來存聽任務
p
nGCD的使用就2個步驟
p定製任務
ü肯定想作的事情

 

p將任務添加到隊列中
üGCD會自動將隊列中的任務取出,放到對應的線程中執行
ü任務的取出遵循隊列的FIFO原則:先進先出,後進後出
p
n執行任務
nGCD中有2個用來執行任務的函數
p用同步的方式執行任務

dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);程序員

üqueue:隊列
üblock:任務

 

p用異步的方式執行任務

dispatch_async(dispatch_queue_t queue, dispatch_block_t block);安全

 

n同步和異步的區別
p同步:在當前線程中執行
p異步:在另外一條線程中執行
n隊列的類型
nGCD的隊列能夠分爲2大類型
p併發隊列(Concurrent Dispatch Queue)
ü可讓多個任務併發(同時)執行(自動開啓多個線程同時執行任務)
ü併發功能只有在異步(dispatch_async)函數下才有效

 

p串行隊列(Serial Dispatch Queue)
ü讓任務一個接着一個地執行(一個任務執行完畢後,再執行下一個任務)
n容易混淆的術語
n有4個術語比較容易混淆:同步、異步、併發、串行
p同步和異步決定了要不要開啓新的線程
ü同步:在當前線程中執行任務,不具有開啓新線程的能力
ü異步:在新的線程中執行任務,具有開啓新線程的能力
ü
p併發和串行決定了任務的執行方式
ü併發:多個任務併發(同時)執行
ü串行:一個任務執行完畢後,再執行下一個任務
ü
p
n併發隊列
nGCD默認已經提供了全局的併發隊列,供整個應用使用,不須要手動建立
p使用dispatch_get_global_queue函數得到全局的併發隊列

dispatch_queue_t dispatch_get_global_queue(多線程

dispatch_queue_priority_t priority, // 隊列的優先級併發

unsigned long flags); // 此參數暫時無用,用0便可異步

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 得到全局併發隊列async

 

n全局併發隊列的優先級
p#define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高
p#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默認(中)
p#define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低
p#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 後臺
n串行隊列
nGCD中得到串行有2種途徑
p使用dispatch_queue_create函數建立串行隊列

dispatch_queue_t函數

dispatch_queue_create(const char *label, // 隊列名稱 spa

dispatch_queue_attr_t attr); // 隊列屬性,通常用NULL便可線程

dispatch_queue_t queue = dispatch_queue_create("cn.itcast.queue", NULL); // 建立orm

dispatch_release(queue); // 非ARC須要釋放手動建立的隊列

 

p使用主隊列(跟主線程相關聯的隊列)
ü主隊列是GCD自帶的一種特殊的串行隊列
ü放在主隊列中的任務,都會放到主線程中執行
ü使用dispatch_get_main_queue()得到主隊列

dispatch_queue_t queue = dispatch_get_main_queue();

 

n各類隊列的執行效果
n線程間通訊示例
n從子線程回到主線程

dispatch_async(

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // 執行耗時的異步操做...

      dispatch_async(dispatch_get_main_queue(), ^{

        // 回到主線程,執行UI刷新操做

        });

});

n延時執行
niOS常見的延時執行有2種方式
p調用NSObject的方法

[self performSelector:@selector(run) withObject:nil afterDelay:2.0];

// 2秒後再調用self的run方法

 

p使用GCD函數

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

    // 2秒後異步執行這裏的代碼...

   

});

n一次性代碼
n使用dispatch_once函數能保證某段代碼在程序運行過程當中只被執行1次

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

    // 只執行1次的代碼(這裏面默認是線程安全的)

});

n隊列組
n有這麼1種需求
p首先:分別異步執行2個耗時的操做
p其次:等2個異步操做都執行完畢後,再回到主線程執行操做
p
n若是想要快速高效地實現上述需求,能夠考慮用隊列組

dispatch_group_t group =  dispatch_group_create();

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // 執行1個耗時的異步操做

});

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // 執行1個耗時的異步操做

});

dispatch_group_notify(group, dispatch_get_main_queue(), ^{

    // 等前面的異步操做都執行完畢後,回到主線程...

});

n單例模式
n單例模式的做用
p能夠保證在程序運行過程,一個類只有一個實例,並且該實例易於供外界訪問
p從而方便地控制了實例個數,並節約系統資源
p
n單例模式的使用場合
p在整個應用程序中,共享一份資源(這份資源只須要建立初始化1次)
p
n單例模式在ARC\MRC環境下的寫法有所不一樣,須要編寫2套不一樣的代碼
p能夠用宏判斷是否爲ARC環境

#if __has_feature(objc_arc)

// ARC

#else

// MRC

#endif

n單例模式 - ARC
nARC中,單例模式的實現
p在.m中保留一個全局的static的實例

static id _instance;

 

p重寫allocWithZone:方法,在這裏建立惟一的實例(注意線程安全)

+ (id)allocWithZone:(struct _NSZone *)zone

{

    @synchronized(self) {

        if (!_instance) {

            _instance = [super allocWithZone:zone];

        }

    }

    return _instance;

}

n單例模式 - ARC
p提供1個類方法讓外界訪問惟一的實例

+ (instancetype)sharedSoundTool

{

    @synchronized(self) {

        if (!_instance) {

            _instance = [[self alloc] init];

        }

    }

    return _instance;

}

n單例模式 – 非ARC
n非ARC中(MRC),單例模式的實現(比ARC多了幾個步驟)
p實現copyWithZone:方法

+ (id)copyWithZone:(struct _NSZone *)zone

{

    return _instance;

}

 

p實現內存管理方法

- (id)retain { return self; }

- (NSUInteger)retainCount { return 1; }

- (oneway void)release {}

- (id)autorelease { return self; }

n
相關文章
相關標籤/搜索