1. 程式人生 > >iOS開發中的併發、序列佇列,同步、非同步任務

iOS開發中的併發、序列佇列,同步、非同步任務

在多執行緒開發中我們經常會遇到這些概念:併發佇列、序列佇列、同步任務、非同步任務。我們將這四個概念進行組合會有四種結果:序列佇列+同步任務、序列佇列+非同步任務、併發佇列+同步任務、併發佇列+非同步任務。我們對這四種結果進行解釋:

1.序列佇列+同步任務:不會開啟新的執行緒,任務逐步完成。

2.序列佇列+非同步任務:開啟新的執行緒,任務逐步完成。

3.併發佇列+同步任務:不會開啟新的執行緒,任務逐步完成。

4.併發佇列+非同步任務:開啟新的執行緒,任務同步完成。

我們如果要讓任務在新的執行緒中完成,應該使用非同步執行緒。為了提高效率,我們還應該將任務放在併發佇列中。因此在開發中使用最多的是併發佇列+非同步任務

。看程式碼:

// 序列佇列+同步任務

- (void)serialSyn{

dispatch_queue_t queue =dispatch_queue_create("serial",DISPATCH_QUEUE_SERIAL);

dispatch_sync(queue, ^{

for (int i =0; i <3; i ++) {

NSLog(@"1---%@", [NSThreadcurrentThread]);

        }

    });

dispatch_sync(queue, ^{

for (int i =0; i <3; i ++) {

NSLog

(@"2---%@", [NSThreadcurrentThread]);

        }

    });

dispatch_sync(queue, ^{

for (int i =0; i <3; i ++) {

NSLog(@"3---%@", [NSThreadcurrentThread]);

        }

    });

}

// 序列佇列+非同步任務

- (void)serialAsyn{

dispatch_queue_t queue =dispatch_queue_create("serial",DISPATCH_QUEUE_SERIAL);

dispatch_async

(queue, ^{

for (int i =0; i <3; i ++) {

NSLog(@"1---%@", [NSThreadcurrentThread]);

        }

    });

dispatch_async(queue, ^{

for (int i =0; i <3; i ++) {

NSLog(@"2---%@", [NSThreadcurrentThread]);

        }

    });

dispatch_async(queue, ^{

for (int i =0; i <3; i ++) {

NSLog(@"3---%@", [NSThreadcurrentThread]);

        }

    });

}

// 併發佇列+同步任務

- (void)concurrenSyn{

dispatch_queue_t queue =dispatch_queue_create("concurrent",DISPATCH_QUEUE_CONCURRENT);

dispatch_sync(queue, ^{

for (int i =0; i <3; i ++) {

NSLog(@"1---%@", [NSThreadcurrentThread]);

        }

    });

dispatch_sync(queue, ^{

for (int i =0; i <3; i ++) {

NSLog(@"2---%@", [NSThreadcurrentThread]);

        }

    });

dispatch_sync(queue, ^{

for (int i =0; i <3; i ++) {

NSLog(@"3---%@", [NSThreadcurrentThread]);

        }

    });

}

// 併發佇列+非同步任務

- (void)concurrentAsyn{

dispatch_queue_t queue =dispatch_queue_create("concurrent",DISPATCH_QUEUE_SERIAL);

dispatch_async(queue, ^{

for (int i =0; i <3; i ++) {

NSLog(@"1---%@", [NSThreadcurrentThread]);

        }

    });

dispatch_async(queue, ^{

for (int i =0; i <3; i ++) {

NSLog(@"2---%@", [NSThreadcurrentThread]);

        }

    });

dispatch_async(queue, ^{

for (int i =0; i <3; i ++) {

NSLog(@"3---%@", [NSThreadcurrentThread]);

        }

    });

}

輸出結果分別為: // 序列佇列+同步任務

2017-12-09 15:50:18.427989+0800 GCD[1044:27175] 1---<NSThread: 0x600000073600>{number = 1, name = main}

2017-12-09 15:50:20.912799+0800 GCD[1044:27277] XPC connection interrupted

2017-12-09 15:50:21.429204+0800 GCD[1044:27175] 1---<NSThread: 0x600000073600>{number = 1, name = main}

2017-12-09 15:50:24.430559+0800 GCD[1044:27175] 1---<NSThread: 0x600000073600>{number = 1, name = main}

2017-12-09 15:50:25.431937+0800 GCD[1044:27175] 2---<NSThread: 0x600000073600>{number = 1, name = main}

2017-12-09 15:50:26.433460+0800 GCD[1044:27175] 2---<NSThread: 0x600000073600>{number = 1, name = main}

2017-12-09 15:50:27.433913+0800 GCD[1044:27175] 2---<NSThread: 0x600000073600>{number = 1, name = main}

2017-12-09 15:50:28.435443+0800 GCD[1044:27175] 3---<NSThread: 0x600000073600>{number = 1, name = main}

2017-12-09 15:50:29.435987+0800 GCD[1044:27175] 3---<NSThread: 0x600000073600>{number = 1, name = main}

2017-12-09 15:50:30.437512+0800 GCD[1044:27175] 3---<NSThread: 0x600000073600>{number = 1, name = main}


// 序列佇列+非同步任務

2017-12-09 16:08:03.242688+0800 GCD[1252:41773] 1---<NSThread: 0x600000276ec0>{number = 3, name = (null)}

2017-12-09 16:08:06.246989+0800 GCD[1252:41773] 1---<NSThread: 0x600000276ec0>{number = 3, name = (null)}

2017-12-09 16:08:09.249206+0800 GCD[1252:41773] 1---<NSThread: 0x600000276ec0>{number = 3, name = (null)}

2017-12-09 16:08:10.250193+0800 GCD[1252:41773] 2---<NSThread: 0x600000276ec0>{number = 3, name = (null)}

2017-12-09 16:08:11.250878+0800 GCD[1252:41773] 2---<NSThread: 0x600000276ec0>{number = 3, name = (null)}

2017-12-09 16:08:12.255908+0800 GCD[1252:41773] 2---<NSThread: 0x600000276ec0>{number = 3, name = (null)}

2017-12-09 16:08:13.258215+0800 GCD[1252:41773] 3---<NSThread: 0x600000276ec0>{number = 3, name = (null)}

2017-12-09 16:08:14.258708+0800 GCD[1252:41773] 3---<NSThread: 0x600000276ec0>{number = 3, name = (null)}

2017-12-09 16:08:15.259192+0800 GCD[1252:41773] 3---<NSThread: 0x600000276ec0>{number = 3, name = (null)}


// 序列佇列+非同步任務

2017-12-09 16:09:23.548551+0800 GCD[1283:42913] 1---<NSThread: 0x604000260540>{number = 1, name = main}

2017-12-09 16:09:25.547003+0800 GCD[1283:43153] XPC connection interrupted

2017-12-09 16:09:26.549830+0800 GCD[1283:42913] 1---<NSThread: 0x604000260540>{number = 1, name = main}

2017-12-09 16:09:29.550406+0800 GCD[1283:42913] 1---<NSThread: 0x604000260540>{number = 1, name = main}

2017-12-09 16:09:30.551134+0800 GCD[1283:42913] 2---<NSThread: 0x604000260540>{number = 1, name = main}

2017-12-09 16:09:31.552655+0800 GCD[1283:42913] 2---<NSThread: 0x604000260540>{number = 1, name = main}

2017-12-09 16:09:32.553861+0800 GCD[1283:42913] 2---<NSThread: 0x604000260540>{number = 1, name = main}

2017-12-09 16:09:33.555326+0800 GCD[1283:42913] 3---<NSThread: 0x604000260540>{number = 1, name = main}

2017-12-09 16:09:34.555842+0800 GCD[1283:42913] 3---<NSThread: 0x604000260540>{number = 1, name = main}

2017-12-09 16:09:35.556267+0800 GCD[1283:42913] 3---<NSThread: 0x604000260540>{number = 1, name = main}


// 併發佇列+非同步任務

2017-12-09 16:10:26.676320+0800 GCD[1309:44938] 3---<NSThread: 0x604000466c40>{number = 3, name = (null)}

2017-12-09 16:10:26.676320+0800 GCD[1309:44937] 2---<NSThread: 0x60000066e380>{number = 4, name = (null)}

2017-12-09 16:10:27.678310+0800 GCD[1309:44938] 3---<NSThread: 0x604000466c40>{number = 3, name = (null)}

2017-12-09 16:10:27.678316+0800 GCD[1309:44937] 2---<NSThread: 0x60000066e380>{number = 4, name = (null)}

2017-12-09 16:10:28.674756+0800 GCD[1309:44935] 1---<NSThread: 0x60000066fa80>{number = 5, name = (null)}

2017-12-09 16:10:28.679805+0800 GCD[1309:44938] 3---<NSThread: 0x604000466c40>{number = 3, name = (null)}

2017-12-09 16:10:28.679798+0800 GCD[1309:44937] 2---<NSThread: 0x60000066e380>{number = 4, name = (null)}

2017-12-09 16:10:31.675355+0800 GCD[1309:44935] 1---<NSThread: 0x60000066fa80>{number = 5, name = (null)}

2017-12-09 16:10:34.678046+0800 GCD[1309:44935] 1---<NSThread: 0x60000066fa80>{number = 5, name = (null)}


看錶格:


注意:

在主佇列中新增同步任務會產生死鎖,進而導致程式崩潰。

程式碼:

- (void)viewDidLoad {

    [superviewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

NSLog(@"===========1");

dispatch_sync(dispatch_get_main_queue(), ^{

NSLog(@"===========2");

    });

NSLog(@"===========3");

}

以上程式碼在打印出1之後就卡死在了dispatch_sync...的程式碼上。

相關推薦

iOS開發併發序列佇列同步非同步任務

在多執行緒開發中我們經常會遇到這些概念:併發佇列、序列佇列、同步任務、非同步任務。我們將這四個概念進行組合會有四種結果:序列佇列+同步任務、序列佇列+非同步任務、併發佇列+同步任務、併發佇列+非同步任

iOS 開發tabBarItem不顯示文字只顯示圖片且圖片居中顯示

//第一頁 HomePageViewController *homePageVC = [[HomePageViewControlleralloc] init]; UINavigationCon

iOS開發配置了國際化檔案但是隻想顯示中文

場景描述:         我的專案配置了國際化檔案,但是英文翻譯還沒有完成,所以,我想在專案中只顯示中文。 解決辦法: 首先,建立NSBundle的Category File->New-&g

阻塞非阻塞同步異步總結

非阻塞 阻塞 同步 異步 總結 阻塞、非阻塞 主要作用在調用方或請求方,如果調用方或請求方是一直等著不幹其它任何事情,就是阻塞方式,如果調用方或請求方在請求之後一邊等待一邊去做其它事情,這種方式則為非阻塞方式。 同步、異步 同步、異步是調用或請求機制,主要看被調用方或被請求方對結果的處理,

iOS開發SQLite簡單使用(基礎用法:建立表查)

SQLite,是一款輕型的資料庫,是遵守ACID的關係型資料庫管理系統,它包含在一個相對小的C庫中。它是D.RichardHipp建立的公有領域專案。它的設計目標是嵌入式的,而且目前已經在很多嵌入式產

iOS開發點選介面空白處或點選背景收起鍵盤

在iOS開發中,我們會在UITextView、UITextField等控制元件裡編輯或者輸入文字結束後,需要關閉鍵盤。最經常的是,點選介面空白處或點選背景收起鍵盤。 通過在在viewDidLoad中新

ios開發資料庫讀取資料牽涉到的日期處理:前一天今天後天一週等

對時間處理,在開發時,時常碰到。一般有獲取具體的年月日和星期,兩個不同時間的差,某一天的前一天或後一天等;在這裡我只介紹獲取具體的年月日和星期,及某一天的前一天或後一天的方法;       對時間的處理一般都會用到NSDate類和NSCalendar類兩個類;      

關於iOS開發圖片處理的一些積累(CoreGraphicCoreImageGPUImageOpenGL)

Core Image 前言 貌似公司最近的專案都是和圖片處理有關,拍拍專案中需要將圖片處理成buffer傳到影象匹配拼接演算法中,需要從原圖中摳出一定範圍的影象再貼到新的背景圖中,需要對靜態圖片進行濾鏡操作等等,所以對這方面接觸的相對多一些。

ios 開發如何設定 uitabbar 裡面 tabbaritem 不顯示文字只顯示圖片圖片垂直居中?

// 矯正TabBar圖片位置,使之垂直居中顯示  CGFloat offset = 5.0;  for (UITabBarItem *item in self.tabbar.items) {  item.imageInsets = UIEdgeInsetsMake(offset, 0, -offset,

IOS開發SVN如何恢復到某一個版本(以Cornerstone為例)

Cornerstone是mac作業系統上一款比較流行的SVN版本管理工具。 如何恢復到某一版本呢? 1。選中你要恢復的工程 2.點選“Working Copy”--->>"Revert..."。 3. 選擇你要恢復的版本號,然後點選“Revert”。 4.

iOS開發調整view層級位置的兩個屬性

控制元件的層級關係和你加入到父檢視的順序有關,也就是先addsubview至父檢視的,層級越低,會被後加入的遮蓋。 可以通過以下函式改變子檢視的層級: 1.Objective-C版本: 將UIView顯示在最前面: - (void)bringSubvi

iOS開發應用內直接跳轉到Appstore評分

1.進入appstore中指定的應用     App Store 上評論的連結地址是 itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+

iOS的三大定時器 iOS開發定時器經常會用到iOS常用的定時器有三種分別是NSTimeCADisplayLink和GCD。

iOS開發中定時器經常會用到,iOS中常用的定時器有三種,分別是NSTime,CADisplayLink和GCD。 NSTimer 方式1 // 建立定時器 NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2 target:

優秀工程師-IOS開發的CGFloatCGPointCGSize和CGRect

1、資料型別: CGFloat: 浮點值的基本型別CGPoint: 表示一個二維座標系中的點CGSize: 表示一個矩形的寬度和高度CGRect: 表示一個矩形的位置和大小 typedef float CGFloat;// 32-bit typedef double C

iOS開發瀏覽器能開啟的URLWebView打不開的處理方法

由於內容簡單,載入不出來是編碼不一致的問題,下面是解決方法:         NSString *encodedString = [url stringByAddingPercentEscapesU

iOS開發如遇到頻繁的Http請求如何取消之前已經發送的Http請求?

我有一個TextField,無論什麼時候當我輸入字元的時候,我appending這個字元到我的url,然後傳送一次請求,我現在需要取消之前的請求。例如當我輸入“shampoo”的時候,我會觸發7次代理方法,也就是我會觸發七次不同的網路請求,那麼有一個問題,這七次發出的請求,響

iOS 開發的訊息機制-代理通知block

關於代理 1.代理時一種設計模式。 使用場景:如果物件B要監聽物件A裡面發什麼了什麼,使用代理。如果物件A想讓物件B去幹活,使用代理。如果物件A中的按鈕或者cell被點選,要把相應的資料傳遞給物件B,使用代理。例如,我們自定義view裡面的button被點選,需要讓控制器知

iOS開發對請求資料出現的一些簡單處理

這裡呢是整理的一位老鳥的東西,好東西得分享 大致實現思路就是迴圈便利做比較,如果發現是NSNull型別的就把值改為空字串;這樣的好處就是當資料請求回來,刪除一下資料裡面為<null>型別的東西,避免在直接取的時候產生程式崩潰問題; 兩個方法,一個返回NSA

IOS開發的CGFloatCGPointCGSize和CGRect

http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CGGeometry/Reference/reference.html CGGeometry類定義幾何元素的結

iOS開發地圖與定位

視圖 編寫 aps 簡單 -a 第三方 span spa margin   不管是QQ還是微信的移動client都少不了定位功能,之前在微信demo中沒有加入定位功能,今天就寫個定位的小demo來了解一下定位和地圖的東西。地圖和定位看上去是挺高大上一東西。其有使用方法比