完整詳解GCD系列(二)dispatch_after;dispatch_apply;dispatch_once

來源:互聯網
上載者:User

標籤:style   io   ar   color   os   使用   sp   strong   on   

一、dispatch_after
功能:延遲一段時間把一項任務提交到隊列中執行,返回之後就不能取消
常用來在在主隊列上順延強制一項任務
函數原型

[plain] view plaincopy
  1. func dispatch_after(_ when: dispatch_time_t,  
  2.                   _ queue: dispatch_queue_t!,  
  3.                   _ block: dispatch_block_t!)  

參數

[plain] view plaincopy
  1.        when 過了多久執行的時間間隔  
  2. queue   提交到的隊列  
  3. block   執行的任務  



例如:可以利用dispatch_after寫一個自己用的Delay函數,delay一段時間在主線程上執行一段代碼

[plain] view plaincopy
  1. func hwcDelay(delay:Double, closure:()->()) {  
  2.     dispatch_after(  
  3.         dispatch_time(  
  4.             DISPATCH_TIME_NOW,  
  5.             Int64(delay * Double(NSEC_PER_SEC))  
  6.         ),  
  7.         dispatch_get_main_queue(), closure)  
  8. }  


只需要這樣使用
hwcDelay(0.5){
//Do everything you want
}
比如,當使用者的應用不滿足某些我們App需要的條件時候(例如,我們的App需要藍芽開啟),然後在APP啟動的時候測到藍芽Off後,應當給使用者一個提示。在view載入完成後,延遲給使用者一個提示,也可以給這個提示添加一些動畫,要比view在載入完成直接顯示提示要有好的多。
舉例
在viewLoad後,延遲1s,提示一個alertview

[plain] view plaincopy
  1. class ViewController: UIViewController{      
  2.     func hwcDelay(delay:Double, closure:()->()) {  
  3.     dispatch_after(  
  4.         dispatch_time(  
  5.             DISPATCH_TIME_NOW,  
  6.             Int64(delay * Double(NSEC_PER_SEC))  
  7.         ),  
  8.         dispatch_get_main_queue(), closure)  
  9. }    
  10.     override func viewDidLoad(){      
  11.         super.viewDidLoad()      
  12.         hwcDelay(1.0){  
  13.         var alertview = UIAlertView(title:"Dispatch_after",message:"Message",delegate:self,cancelButtonTitle:"OK")  
  14.         alertview.show()  
  15.     }            
  16.     }      
  17.     override func didReceiveMemoryWarning(){      
  18.         super.didReceiveMemoryWarning()      
  19.     }      
  20. }   


二、dispatch_apply
功能:把一項任務提交到隊列中多次執行,具體是並存執行還是串列執行由隊列本身決定.注意,dispatch_apply不會立刻返回,在執行完畢後才會返回,是同步的調用。

[plain] view plaincopy
  1. func dispatch_apply(_ iterations: UInt,  
  2.                   _ queue: dispatch_queue_t!,  
  3.                   _ block: ((UInt) -> Void)!)  

參數

[plain] view plaincopy
  1. iterations  執行的次數  
  2.     queue       提交到的隊列  
  3.     block       執行的任務  


那麼,何時使用這個函數呢?從它的功能不難看出,如果我們可以把不相關的迴圈提交到後台線程並存執行,並且迴圈任務調度到後台執行的效率提高,能抵消掉隊列調度本身的開銷,那麼效率會顯著提高。

舉例
比如我有一個數組,儲存了一系列對象,初始化的時候,這些對象都要調用一次某函數來進行相關的計算。這些計算相互沒有影響。這時,我們就可以用dispatch_apply來使用非同步隊列來初始化.這裡把這種情況進行簡化

[plain] view plaincopy
  1. class ViewController: UIViewController{      
  2.     var hwcarray = ["hello","hwc","hellohwc"]  
  3.     override func viewDidLoad(){      
  4.         super.viewDidLoad()      
  5.         dispatch_apply(3,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)){  
  6.         (index:UInt) -> () in  
  7.         var expObject = self.hwcarray[Int(index)] as NSString  
  8.         NSLog("%d",expObject.length)  
  9.     }    
  10.     NSLog("Dispatch_after is over")       
  11.     }      
  12.     override func didReceiveMemoryWarning(){      
  13.         super.didReceiveMemoryWarning()      
  14.     }      
  15. }   

可以看到,輸出是

[plain] view plaincopy
  1. 3  
  2. 5  
  3. 8  
  4. dispatch_after is over  

由於這樣會阻塞主線程,而下文又與dispatch_apply的執行結果無關,所以可以在非同步隊列中掉dispatch_apply,然後執行完成後進行通知

[plain] view plaincopy
  1. class ViewController: UIViewController{      
  2.     var hwcarray = ["hello","hwc","hellohwc"]  
  3.     override func viewDidLoad(){   
  4.         super.viewDidLoad()  
  5.     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)){  
  6.      dispatch_apply(3,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)){  
  7.         (index:UInt) -> () in  
  8.         var expObject = self.hwcarray[Int(index)] as NSString  
  9.         NSLog("%d",expObject.length)  
  10.      }  
  11.      NSLog("Dispatch_after in global queue is over")    
  12.     }      
  13.          
  14.     NSLog("Dispatch_after in main queue is over")       
  15.     }      
  16.     override func didReceiveMemoryWarning(){      
  17.         super.didReceiveMemoryWarning()      
  18.     }      
  19. }  

這樣輸出為

[plain] view plaincopy
  1. 8  
  2. Dispatch_after in main queue is over  
  3. 3  
  4. 5  
  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
  1. class hwcSingleton {  
  2.      var testVariable:Int!  
  3.      func print(){  
  4.     testVariable = testVariable + 1  
  5.     println(testVariable)  
  6.     }  
  7.     class var sharedObject: hwcSingleton {  
  8.         struct StaticStruct {  
  9.             static var predicate : dispatch_once_t = 0  
  10.             static var instance : hwcSingleton? = nil  
  11.         }  
  12.         dispatch_once(&StaticStruct.predicate) {  
  13.             StaticStruct.instance = hwcSingleton()  
  14.        StaticStruct.instance?.testVariable = 10  
  15.         }  
  16.         return StaticStruct.instance!  
  17.     }  

完整詳解GCD系列(二)dispatch_after;dispatch_apply;dispatch_once

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.