標籤:style io ar color os 使用 sp strong on
一、dispatch_after
功能:延遲一段時間把一項任務提交到隊列中執行,返回之後就不能取消
常用來在在主隊列上順延強制一項任務
函數原型
[plain] view plaincopy
- func dispatch_after(_ when: dispatch_time_t,
- _ queue: dispatch_queue_t!,
- _ block: dispatch_block_t!)
參數
[plain] view plaincopy
- when 過了多久執行的時間間隔
- queue 提交到的隊列
- block 執行的任務
例如:可以利用dispatch_after寫一個自己用的Delay函數,delay一段時間在主線程上執行一段代碼
[plain] view plaincopy
- func hwcDelay(delay:Double, closure:()->()) {
- dispatch_after(
- dispatch_time(
- DISPATCH_TIME_NOW,
- Int64(delay * Double(NSEC_PER_SEC))
- ),
- dispatch_get_main_queue(), closure)
- }
只需要這樣使用
hwcDelay(0.5){
//Do everything you want
}
比如,當使用者的應用不滿足某些我們App需要的條件時候(例如,我們的App需要藍芽開啟),然後在APP啟動的時候測到藍芽Off後,應當給使用者一個提示。在view載入完成後,延遲給使用者一個提示,也可以給這個提示添加一些動畫,要比view在載入完成直接顯示提示要有好的多。
舉例
在viewLoad後,延遲1s,提示一個alertview
[plain] view plaincopy
- class ViewController: UIViewController{
- func hwcDelay(delay:Double, closure:()->()) {
- dispatch_after(
- dispatch_time(
- DISPATCH_TIME_NOW,
- Int64(delay * Double(NSEC_PER_SEC))
- ),
- dispatch_get_main_queue(), closure)
- }
- override func viewDidLoad(){
- super.viewDidLoad()
- hwcDelay(1.0){
- var alertview = UIAlertView(title:"Dispatch_after",message:"Message",delegate:self,cancelButtonTitle:"OK")
- alertview.show()
- }
- }
- override func didReceiveMemoryWarning(){
- super.didReceiveMemoryWarning()
- }
- }
二、dispatch_apply
功能:把一項任務提交到隊列中多次執行,具體是並存執行還是串列執行由隊列本身決定.注意,dispatch_apply不會立刻返回,在執行完畢後才會返回,是同步的調用。
[plain] view plaincopy
- func dispatch_apply(_ iterations: UInt,
- _ queue: dispatch_queue_t!,
- _ block: ((UInt) -> Void)!)
參數
[plain] view plaincopy
- iterations 執行的次數
- queue 提交到的隊列
- block 執行的任務
那麼,何時使用這個函數呢?從它的功能不難看出,如果我們可以把不相關的迴圈提交到後台線程並存執行,並且迴圈任務調度到後台執行的效率提高,能抵消掉隊列調度本身的開銷,那麼效率會顯著提高。
舉例
比如我有一個數組,儲存了一系列對象,初始化的時候,這些對象都要調用一次某函數來進行相關的計算。這些計算相互沒有影響。這時,我們就可以用dispatch_apply來使用非同步隊列來初始化.這裡把這種情況進行簡化
[plain] view plaincopy
- class ViewController: UIViewController{
- var hwcarray = ["hello","hwc","hellohwc"]
- override func viewDidLoad(){
- super.viewDidLoad()
- dispatch_apply(3,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)){
- (index:UInt) -> () in
- var expObject = self.hwcarray[Int(index)] as NSString
- NSLog("%d",expObject.length)
- }
- NSLog("Dispatch_after is over")
- }
- override func didReceiveMemoryWarning(){
- super.didReceiveMemoryWarning()
- }
- }
可以看到,輸出是
[plain] view plaincopy
- 3
- 5
- 8
- dispatch_after is over
由於這樣會阻塞主線程,而下文又與dispatch_apply的執行結果無關,所以可以在非同步隊列中掉dispatch_apply,然後執行完成後進行通知
[plain] view plaincopy
- class ViewController: UIViewController{
- var hwcarray = ["hello","hwc","hellohwc"]
- override func viewDidLoad(){
- super.viewDidLoad()
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)){
- dispatch_apply(3,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)){
- (index:UInt) -> () in
- var expObject = self.hwcarray[Int(index)] as NSString
- NSLog("%d",expObject.length)
- }
- NSLog("Dispatch_after in global queue is over")
- }
-
- NSLog("Dispatch_after in main queue is over")
- }
- override func didReceiveMemoryWarning(){
- super.didReceiveMemoryWarning()
- }
- }
這樣輸出為
[plain] view plaincopy
- 8
- Dispatch_after in main queue is over
- 3
- 5
- Dispatch_after in global queue is over
可以看到,相對主隊列(主線程)是非同步,在global隊列中是並存執行的
三、dispatch_once
功能:保證在APP運行期間,block中的代碼只執行一次
func dispatch_once(_ predicate: UnsafeMutablePointer<dispatch_once_t>,
_ block: dispatch_block_t!)
參數
predicate 用來判斷提交的block是否執行完成
block 執行一次的任務
dispatch_once的經典實用情境是單例
單例代碼:
[plain] view plaincopy
- class hwcSingleton {
- var testVariable:Int!
- func print(){
- testVariable = testVariable + 1
- println(testVariable)
- }
- class var sharedObject: hwcSingleton {
- struct StaticStruct {
- static var predicate : dispatch_once_t = 0
- static var instance : hwcSingleton? = nil
- }
- dispatch_once(&StaticStruct.predicate) {
- StaticStruct.instance = hwcSingleton()
- StaticStruct.instance?.testVariable = 10
- }
- return StaticStruct.instance!
- }
- }
完整詳解GCD系列(二)dispatch_after;dispatch_apply;dispatch_once