iOS多線程與網絡開發之多線程GCD

郝萌主傾心貢獻,尊重做者的勞動成果。請勿轉載。安全

假設文章對您有所幫助,歡迎給做者捐贈。支持郝萌主。捐贈數額任意。重在心意^_^ 
併發

我要捐贈: 點擊捐贈異步

Cocos2d-X源代碼下載:點我傳送async

遊戲官方下載:http://dwz.cn/RwTjl函數

遊戲視頻預覽:http://dwz.cn/RzHHdpost

遊戲開發博客:http://dwz.cn/RzJzIspa

遊戲源代碼傳送http://dwz.cn/Nret1.net


A.GCD基本使用
1.GCD的概念
什麼是GCD
全稱是Grand Central Dispatch,可譯爲「牛逼的中樞調度器」
純C語言,提供了不少強大的函數

GCD的優點
GCD是蘋果公司爲多核的並行運算提出的解決方式
GCD會本身主動利用不少其它的CPU內核(比方雙核、四核)
GCD會本身主動管理線程的生命週期(建立線程、調度任務、銷燬線程)
程序猿僅僅需要告訴GCD想要運行什麼任務。不需要編寫不論什麼線程管理代碼
 
2.任務和隊列
GCD中有2個核心概念
任務:運行什麼操做
隊列:用來存聽任務

GCD的使用就2個步驟
定製任務
肯定想作的事情

將任務加入到隊列中
GCD會本身主動將隊列中的任務取出,放到相應的線程中運行
任務的取出遵循隊列的FIFO原則:先進先出,後進後出
 
3.運行任務
GCD中有2個用來運行任務的函數
用同步的方式運行任務
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
queue:隊列
block:任務

用異步的方式運行任務
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

同步和異步的差異
同步:在當前線程中運行
異步:在還有一條線程中運行
 
4.隊列的類型
GCD的隊列可以分爲2大類型
併發隊列(Concurrent Dispatch Queue)
可以讓多個任務併發(同一時候)運行(本身主動開啓多個線程同一時候運行任務)
併發功能僅僅有在異步(dispatch_async)函數下才有效

串行隊列(Serial Dispatch Queue)
讓任務一個接着一個地運行(一個任務運行完成後,再運行下一個任務)
 
5.同步&異步 串行&併發
有4個術語比較easy混淆:同步、異步、併發、串行
同步和異步決定了要不要開啓新的線程
同步:在當前線程中運行任務,不具有開啓新線程的能力
異步:在新的線程中運行任務。具有開啓新線程的能力

併發和串行決定了任務的運行方式
併發:多個任務併發(同一時候)運行
串行:一個任務運行完成後。再運行下一個任務
 
6.併發隊列
GCD默認已經提供了全局的併發隊列。供整個應用使用,不需要手動建立
使用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); // 得到全局併發隊列

全局併發隊列的優先級
#define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默認(中)
#define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 後臺
 
7.串行隊列
GCD中得到串行有2種途徑
使用dispatch_queue_create函數建立串行隊列
dispatch_queue_t
dispatch_queue_create(const char *label, // 隊列名稱 
dispatch_queue_attr_t attr); // 隊列屬性,通常用NULL就能夠
dispatch_queue_t queue = dispatch_queue_create("cn.itcast.queue", NULL); // 建立
dispatch_release(queue); // 非ARC需要釋放手動建立的隊列

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

8.各類組合
Image(35)
 
9.線程間通訊
從子線程回到主線程
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 運行耗時的異步操做...
      dispatch_async(dispatch_get_main_queue(), ^{
        // 回到主線程,運行UI刷新操做
        });
});
 
10.延時運行
iOS常見的延時運行有2種方式
調用NSObject的方法
[self performSelector:@selector(run) withObject:nil afterDelay:2.0];
// 2秒後再調用self的run方法

使用GCD函數
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    // 2秒後異步運行這裏的代碼...
   
});
 
 
11.一次性代碼
使用dispatch_once函數能保證某段代碼在程序運行過程當中僅僅被運行1次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    // 僅僅運行1次的代碼(這裏面默認是線程安全的)
});
 
 
12.隊列組group
有這麼1種需求
首先:分別異步運行2個耗時的操做
其次:等2個異步操做都運行完成後,再回到主線程運行操做

假設想要高速高效地實現上述需求,可以考慮用隊列組
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(), ^{
    // 等前面的異步操做都運行完成後,回到主線程...
});
 
 
B.單例模式
1.單例模式概念
單例模式的做用
可以保證在程序運行過程,一個類僅僅有一個實例。而且該實例易於供外界訪問
從而方便地控制了實例個數。並節約系統資源

單例模式的使用場合
在整個應用程序中,共享一份資源(這份資源僅僅需要建立初始化1次)

單例模式在ARC\MRC環境下的寫法有所不一樣,需要編寫2套不一樣的代碼
可以用宏推斷是否爲ARC環境
#if __has_feature(objc_arc)
// ARC
#else
// MRC
#endif
 
2.單例模式-ARC
ARC中,單例模式的實現
在.m中保留一個全局的static的實例
static id _instance;

重寫allocWithZone:方法,在這裏建立惟一的實例(注意線程安全)
+ (id)allocWithZone:(struct _NSZone *)zone
{
    @synchronized(self) {
        if (!_instance) {
            _instance = [super allocWithZone:zone];
        }
    }
    return _instance;
}
 
提供1個類方法讓外界訪問惟一的實例
+ (instancetype)sharedSoundTool
{
    @synchronized(self) {
        if (!_instance) {
            _instance = [[self alloc] init];
        }
    }
    return _instance;
}
 
3.單例模式-非ARC
非ARC中(MRC),單例模式的實現(比ARC多了幾個步驟)
實現copyWithZone:方法
+ (id)copyWithZone:(struct _NSZone *)zone
{
    return _instance;
}

實現內存管理方法
- (id)retain { return self; }
- (NSUInteger)retainCount { return 1; }
- (oneway void)release {}
- (id)autorelease { return self; }

郝萌主傾心貢獻,尊重做者的勞動成果,請勿轉載。線程

假設文章對您有所幫助,歡迎給做者捐贈,支持郝萌主。捐贈數額任意,重在心意^_^ 
orm

我要捐贈: 點擊捐贈

Cocos2d-X源代碼下載:點我傳送

遊戲官方下載:http://dwz.cn/RwTjl

遊戲視頻預覽:http://dwz.cn/RzHHd

遊戲開發博客:http://dwz.cn/RzJzI

遊戲源代碼傳送http://dwz.cn/Nret1

相關文章
相關標籤/搜索