先了解幾個概念
1/進程與線程
都是操作系統分配和調度的程序運行的基本單元,實現對應用的並發性
進程是包含了某些資源的內存區域。進程所包含的一個或多個執行單元稱為線程
進程有一個私有的虛擬地址空間,只有被包含的線程訪問一個進程至少包含一個線程,即主線程
線程是進程的一個實體,比進程更小的能獨立運行的基本單位
線程不擁有系統資源,只有一點在運行中必不可少的資源(堆棧和局部變量)可以和同屬一個進程的其他線程共享進程的所擁有的資源
2/多線程
為了防止主線程堵塞,增加運行效率等等的最佳方法
所以更新UI操作全部需要在主線程裡面操作
3/隊列(Queue)
4/同步(Synchronous)和異步(Asynchronous)
Synchronous:和跑接力賽一樣,第一棒的人跑到位置傳遞接力棒第二人才能跑,否則就是等著第一個人到來
Asynchronous:魚池一樣,沒有先後順序.也不用等待
5/串行(Serial)和並發(Concurrent)
Serial:同時只執行一個任務,又稱private dispatch queues,一般用於訪問特定的數據或資源,但Serial queue與Serial queue 之間是並發執行的.
Concurrent:又稱global dispath queue 可以並發執行多個任務,執行完成的順序是隨機的.
Main dispatch queue:全局可用的serial queue 應用程序住線程上執行任務的
6/IOS中對於線程的操作有三種:GCD,NSThread,Cocoa NSOperation
終於可以進去到編碼階段了。
7/GCD(Grand Central Dispatch)
Apple在底層已經封裝好了線程管理,需要把任務放在GCD的Dispatch Queue隊列中GCD底層還是使用線程實現的。
GCD中的FIFO隊列稱為dispath queue
為了防止界面卡死,把一些操作寫進一個線程裡面(讀取網絡數據,IO等) 然後通知主線程更新UI
//異步的方式在主線程更新界面,主隊列:dispatch_get_main_queue
dispatch_async(dispatch_get_main_queue(), { () -> Void in
//主線程 用於更新UI界面的
})
//同步的方式執行,全局隊列:dispatch_get_global_queue
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
})
*注:global_queue 參數1優先級順序高到低:
DISPATCH_QUEUE_PRIORITY_HIGH
DISPATCH_QUEUE_PRIORITY_DEFAULT
DISPATCH_QUEUE_PRIORITY_LOW
DISPATCH_QUEUE_PRIORITY_BACKGROUND
除了以上兩種隊列,還可以自定義隊列
let my_dispatch:dispatch_queue_t = dispatch_queue_create("com.maiziedu", nil)
//com.maiziedu:代表標示符,第二個參數表示什麼隊列:DISPATCH_QUEUE_CONCURRENT/DISPATCH_QUEUE_SERIAL
//GCD延遲
let my_dispatch_time:dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, (Int64)(NSEC_PER_SEC * 2))
dispatch_after(my_dispatch_time, dispatch_get_main_queue()) { () -> Void in
}
//GCD重復執行 執行耗時 執行次數不多的
dispatch_apply(6, dispatch_get_main_queue()) { (UInt i) -> Void in
//執行6次
}
//調度組
let my_dispatch_group:dispatch_group_t = dispatch_group_create()
dispatch_group_async(my_dispatch_group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) { () -> Void in
//任務1
}
dispatch_group_async(my_dispatch_group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) { () -> Void in
//任務2
}
//任務組的所有任務都完成之後回調
dispatch_group_notify(my_dispatch_group, dispatch_get_main_queue()) { () -> Void in
}
dispatch_group_wait(my_dispatch_group, DISPATCH_TIME_FOREVER)//同步執行
//暫停隊列
dispatch_suspend(my_dispatch)
//恢復隊列
dispatch_resume(my_dispatch)
8/NSOperation/NSOperationQueue
NSOperation 是抽象基類
1.使用系統提供的子類NSBlockOperation
let myQueue = NSBlockOperation()
NSOperationQueue().addOperation(myQueue)
//NSBlockOperation
myQueue.start() 同步 阻塞住線程
myQueue.cancel() 取消
myQueue.completionBlock = {
//執行完成監聽
}
myQueue.addExecutionBlock { () -> Void in
//追加 並行
}
let myQueue2 = NSBlockOperation()
//操作1依賴於操作2 執行順序改變
myQueue1.addDependency(myQueue2)
//修改操作的優先級
myQueue2.queuePriority = NSOperationQueuePriority.High
//隊列暫停
NSOperationQueue的suspended 屬性 true為暫停
2.自定義類繼承
class Wk: NSOperation {
override func main(){
//執行操作
}
}
9/NSThread
//線程阻塞2秒
NSThread.sleepForTimeInterval(2)
//線程阻塞到什麼時間
NSThread.sleepUntilDate()
//多線程的解決方案
NSThread.detachNewThreadSelector("gi", toTarget: self, withObject: nil)
//獲取當前線程
NSThread.currentThread()
//也有start 和 cancel 方法 和上面一樣
可以自定義個類實現NSThread的main方法
10/三者比較
總結了IOS中對於多線程的操作,對比一下三者
NSThread: (優)輕量級,使用簡單
(缺)自己管理生命周期、線程同步、加鎖、睡眠以及喚醒等
NSOperation:(優)不需要關心線程管理,數據同步的事情 面向對象.實現了GCD中不容易實現的特性:限制最大並發數、操作之間的依賴關系
GCD:IOS4.0以上使用 是替代NSThread, NSOperation的高效和強大的技術.Block定義任務
11/補充
防止讀著學著
var MyT:dispatch_once_t = 0
dispatch_once(&MyT, { () -> Void in
//只執行一次
})
dispatch_barrier_async(自定義隊列) { () -> Void in
}